summaryrefslogtreecommitdiff
path: root/pr/src/misc
diff options
context:
space:
mode:
Diffstat (limited to 'pr/src/misc')
-rw-r--r--pr/src/misc/Makefile.in12
-rw-r--r--pr/src/misc/compile-et.pl2
-rw-r--r--pr/src/misc/pralarm.c4
-rw-r--r--pr/src/misc/prcountr.c12
-rw-r--r--pr/src/misc/prdtoa.c228
-rw-r--r--pr/src/misc/prenv.c2
-rw-r--r--pr/src/misc/prerr.c5
-rw-r--r--pr/src/misc/prerr.et1
-rw-r--r--pr/src/misc/prerr.properties2
-rw-r--r--pr/src/misc/prerror.c4
-rw-r--r--pr/src/misc/prinit.c56
-rw-r--r--pr/src/misc/prinrval.c4
-rw-r--r--pr/src/misc/prlong.c4
-rw-r--r--pr/src/misc/prnetdb.c669
-rw-r--r--pr/src/misc/prolock.c11
-rw-r--r--pr/src/misc/prrng.c10
-rw-r--r--pr/src/misc/prsystem.c19
-rw-r--r--pr/src/misc/prtime.c67
-rw-r--r--pr/src/misc/prtpool.c6
-rw-r--r--pr/src/misc/prtrace.c11
20 files changed, 916 insertions, 213 deletions
diff --git a/pr/src/misc/Makefile.in b/pr/src/misc/Makefile.in
index 114e110b..afc4b631 100644
--- a/pr/src/misc/Makefile.in
+++ b/pr/src/misc/Makefile.in
@@ -82,12 +82,14 @@ RELEASE_BINS = $(srcdir)/compile-et.pl $(srcdir)/prerr.properties
include $(topsrcdir)/config/rules.mk
-# An AIX Optimization bug causes PR_dtoa() to produce wrong result.
-# This suppresses optimization for this single compilation unit.
-ifeq ($(OS_ARCH), AIX)
-$(OBJDIR)/prdtoa.o: prdtoa.c
+# 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)
- $(CC) -o $@ -c $(filter-out -O, $(CFLAGS)) $<
+ $(CC) -Fo$@ -c $(CFLAGS) -Op $(call abspath,$<)
endif
#
diff --git a/pr/src/misc/compile-et.pl b/pr/src/misc/compile-et.pl
index c1c55dd7..8fafcb7b 100644
--- a/pr/src/misc/compile-et.pl
+++ b/pr/src/misc/compile-et.pl
@@ -129,7 +129,7 @@ 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", "() {\n";
+print C "void ", $table_name, "_InitializePRErrorTable", "(void) {\n";
print C " PR_ErrorInstallTable(&et);\n";
print C "}\n";
diff --git a/pr/src/misc/pralarm.c b/pr/src/misc/pralarm.c
index 488ce5a4..81b251d9 100644
--- a/pr/src/misc/pralarm.c
+++ b/pr/src/misc/pralarm.c
@@ -116,7 +116,7 @@ static PRIntervalTime pr_PredictNextNotifyTime(PRAlarmID *id)
id->lastNotify = id->nextNotify; /* just keeping track of things */
id->nextNotify = (PRIntervalTime)(offsetFromEpoch + 0.5);
- delta = id->nextNotify - id->nextNotify;
+ delta = id->nextNotify - id->lastNotify;
return delta;
} /* pr_PredictNextNotifyTime */
@@ -180,7 +180,7 @@ static void PR_CALLBACK pr_alarmNotifier(void *arg)
} /* pr_alarm_notifier */
-PR_IMPLEMENT(PRAlarm*) PR_CreateAlarm()
+PR_IMPLEMENT(PRAlarm*) PR_CreateAlarm(void)
{
PRAlarm *alarm = PR_NEWZAP(PRAlarm);
if (alarm != NULL)
diff --git a/pr/src/misc/prcountr.c b/pr/src/misc/prcountr.c
index 850f7bcd..b5f6ae23 100644
--- a/pr/src/misc/prcountr.c
+++ b/pr/src/misc/prcountr.c
@@ -68,7 +68,6 @@
**
*/
-#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
#include "prcountr.h"
#include "prclist.h"
#include "prlock.h"
@@ -502,14 +501,3 @@ PR_IMPLEMENT(PRCounterHandle)
return((PRCounterHandle)rnp);
} /* end PR_FindNextCounterRname() */
-
-
-#else /* !(defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)) */
-/*
-** NSPR Counters are not defined in this case
-**
-**
-*/
-/* Some compilers don't like an empty compilation unit. */
-static int dummy = 0;
-#endif /* defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) */
diff --git a/pr/src/misc/prdtoa.c b/pr/src/misc/prdtoa.c
index e2e715fe..78b509e6 100644
--- a/pr/src/misc/prdtoa.c
+++ b/pr/src/misc/prdtoa.c
@@ -97,6 +97,9 @@
* 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 Sudden_Underflow for IEEE-format machines without gradual
* underflow (i.e., that flush to zero on underflow).
@@ -123,8 +126,16 @@
* 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.
+ * #define YES_ALIAS to permit aliasing certain double values with
+ * arrays of unsigned Longs. This leads to slightly better code with
+ * some compilers and was always used prior to 19990916, but it
+ * is not strictly legal and can cause trouble with aggressively
+ * optimizing compilers (e.g., gcc 2.95.1 under -O2).
*/
-#if defined(IS_LITTLE_ENDIAN)
+#if defined(__arm) || defined(__arm__) || defined(__arm26__) \
+ || defined(__arm32__)
+#define IEEE_ARM
+#elif defined(IS_LITTLE_ENDIAN)
#define IEEE_8087
#else
#define IEEE_MC68k
@@ -164,6 +175,9 @@ extern void *MALLOC(size_t);
#ifdef IEEE_8087
#define IEEE_ARITHMETIC
#endif
+#ifdef IEEE_ARM
+#define IEEE_ARITHMETIC
+#endif
#ifdef IEEE_ARITHMETIC
#define DBL_DIG 15
@@ -197,6 +211,16 @@ extern void *MALLOC(size_t);
#endif
#else
#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(MACOS_DEPLOYMENT_TARGET) && (MACOS_DEPLOYMENT_TARGET < 100200)
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+#endif
#endif
#ifndef __MATH_H__
#include "math.h"
@@ -212,10 +236,14 @@ extern void *MALLOC(size_t);
#define Sign_Extend(a,b) /*no-op*/
#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.
+#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; unsigned Long L[2]; } U;
+
+#ifdef YES_ALIAS
+#define dval(x) x
#ifdef IEEE_8087
#define word0(x) ((unsigned Long *)&x)[1]
#define word1(x) ((unsigned Long *)&x)[0]
@@ -223,12 +251,22 @@ Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
#define word0(x) ((unsigned Long *)&x)[0]
#define word1(x) ((unsigned Long *)&x)[1]
#endif
+#else
+#ifdef IEEE_8087
+#define word0(x) ((U*)&x)->L[1]
+#define word1(x) ((U*)&x)->L[0]
+#else
+#define word0(x) ((U*)&x)->L[0]
+#define word1(x) ((U*)&x)->L[1]
+#endif
+#define dval(x) ((U*)&x)->d
+#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)
+#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
@@ -242,7 +280,7 @@ Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
-#if defined(IEEE_8087) + defined(IEEE_MC68k)
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM)
#define Exp_shift 20
#define Exp_shift1 20
#define Exp_msk1 0x100000
@@ -904,7 +942,7 @@ static double ulp(double x)
}
}
#endif
- return a;
+ return dval(a);
}
static double
@@ -974,7 +1012,7 @@ ret_d:
#undef d0
#undef d1
#endif
- return d;
+ return dval(d);
}
static Bigint *
@@ -1117,8 +1155,8 @@ ratio
double da, db;
PRInt32 k, ka, kb;
- da = b2d(a, &ka);
- db = b2d(b, &kb);
+ dval(da) = b2d(a, &ka);
+ dval(db) = b2d(b, &kb);
#ifdef Pack_32
k = ka - kb + 32*(a->wds - b->wds);
#else
@@ -1128,13 +1166,13 @@ ratio
if (k > 0) {
word0(da) += (k >> 2)*Exp_msk1;
if (k &= 3)
- da *= 1 << k;
+ dval(da) *= 1 << k;
}
else {
k = -k;
word0(db) += (k >> 2)*Exp_msk1;
if (k &= 3)
- db *= 1 << k;
+ dval(db) *= 1 << k;
}
#else
if (k > 0)
@@ -1144,7 +1182,7 @@ ratio
word0(db) += k*Exp_msk1;
}
#endif
- return da / db;
+ return dval(da) / dval(db);
}
static CONST double
@@ -1180,6 +1218,16 @@ void _PR_InitDtoa(void)
p5s_lock = PR_NewLock();
}
+void _PR_CleanupDtoa(void)
+{
+ PR_DestroyLock(freelist_lock);
+ freelist_lock = NULL;
+ PR_DestroyLock(p5s_lock);
+ p5s_lock = NULL;
+
+ /* FIXME: deal with freelist and p5s. */
+}
+
#if defined(HAVE_WATCOM_BUG_1)
PRFloat64 __pascal __loadds __export
#else
@@ -1199,7 +1247,7 @@ PR_strtod(CONST char *s00, char **se)
if (!_pr_initialized) _PR_ImplicitInitialization();
sign = nz0 = nz = 0;
- rv = 0.;
+ dval(rv) = 0.;
for(s = s00;;s++) switch(*s) {
case '-':
sign = 1;
@@ -1321,9 +1369,9 @@ dig_done:
if (!nd0)
nd0 = nd;
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
- rv = y;
+ dval(rv) = y;
if (k > 9)
- rv = tens[k - 9] * rv + z;
+ dval(rv) = tens[k - 9] * dval(rv) + z;
bd0 = 0;
if (nd <= DBL_DIG
#ifndef RND_PRODQUOT
@@ -1337,7 +1385,7 @@ dig_done:
#ifdef VAX
goto vax_ovfl_check;
#else
- /* rv = */ rounded_product(rv, tens[e]);
+ /* rv = */ rounded_product(dval(rv), tens[e]);
goto ret;
#endif
}
@@ -1347,27 +1395,27 @@ dig_done:
* this for larger i values.
*/
e -= i;
- rv *= tens[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(rv, tens[e]);
+ /* 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(rv, tens[e]);
+ /* rv = */ rounded_product(dval(rv), tens[e]);
#endif
goto ret;
}
}
#ifndef Inaccurate_Divide
else if (e >= -Ten_pmax) {
- /* rv = */ rounded_quotient(rv, tens[-e]);
+ /* rv = */ rounded_quotient(dval(rv), tens[-e]);
goto ret;
}
#endif
@@ -1378,13 +1426,13 @@ dig_done:
if (e1 > 0) {
if ((i = e1 & 15) != 0)
- rv *= tens[i];
+ dval(rv) *= tens[i];
if (e1 &= ~15) {
if (e1 > DBL_MAX_10_EXP) {
ovfl:
PR_SetError(PR_RANGE_ERROR, 0);
#ifdef __STDC__
- rv = HUGE_VAL;
+ dval(rv) = HUGE_VAL;
#else
/* Can't trust HUGE_VAL */
#ifdef IEEE_Arith
@@ -1402,10 +1450,10 @@ dig_done:
if (e1 >>= 4) {
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
- rv *= bigtens[j];
+ dval(rv) *= bigtens[j];
/* The last multiplication could overflow. */
word0(rv) -= P*Exp_msk1;
- rv *= bigtens[j];
+ dval(rv) *= bigtens[j];
if ((z = word0(rv) & Exp_mask)
> Exp_msk1*(DBL_MAX_EXP+Bias-P))
goto ovfl;
@@ -1424,23 +1472,23 @@ dig_done:
else if (e1 < 0) {
e1 = -e1;
if ((i = e1 & 15) != 0)
- rv /= tens[i];
+ dval(rv) /= tens[i];
if (e1 &= ~15) {
e1 >>= 4;
if (e1 >= 1 << n_bigtens)
goto undfl;
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
- rv *= tinytens[j];
+ dval(rv) *= tinytens[j];
/* The last multiplication could underflow. */
- rv0 = rv;
- rv *= tinytens[j];
- if (!rv) {
- rv = 2.*rv0;
- rv *= tinytens[j];
- if (!rv) {
+ dval(rv0) = dval(rv);
+ dval(rv) *= tinytens[j];
+ if (!dval(rv)) {
+ dval(rv) = 2.*dval(rv0);
+ dval(rv) *= tinytens[j];
+ if (!dval(rv)) {
undfl:
- rv = 0.;
+ dval(rv) = 0.;
PR_SetError(PR_RANGE_ERROR, 0);
if (bd0)
goto retfree;
@@ -1464,7 +1512,7 @@ dig_done:
for(;;) {
bd = Balloc(bd0->k);
Bcopy(bd, bd0);
- bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
bs = i2b(1);
if (e >= 0) {
@@ -1576,12 +1624,12 @@ dig_done:
break;
#endif
if (dsign)
- rv += ulp(rv);
+ dval(rv) += ulp(dval(rv));
#ifndef ROUND_BIASED
else {
- rv -= ulp(rv);
+ dval(rv) -= ulp(dval(rv));
#ifndef Sudden_Underflow
- if (!rv)
+ if (!dval(rv))
goto undfl;
#endif
}
@@ -1632,10 +1680,10 @@ dig_done:
/* Check for overflow */
if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
- rv0 = rv;
+ dval(rv0) = dval(rv);
word0(rv) -= P*Exp_msk1;
- adj = aadj1 * ulp(rv);
- rv += adj;
+ 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)
@@ -1650,10 +1698,10 @@ dig_done:
else {
#ifdef Sudden_Underflow
if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
- rv0 = rv;
+ dval(rv0) = dval(rv);
word0(rv) += P*Exp_msk1;
- adj = aadj1 * ulp(rv);
- rv += adj;
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
#ifdef IBM
if ((word0(rv) & Exp_mask) < P*Exp_msk1)
#else
@@ -1671,8 +1719,8 @@ dig_done:
word0(rv) -= P*Exp_msk1;
}
else {
- adj = aadj1 * ulp(rv);
- rv += adj;
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
}
#else
/* Compute adj so that the IEEE rounding rules will
@@ -1687,8 +1735,8 @@ dig_done:
if (!dsign)
aadj1 = -aadj1;
}
- adj = aadj1 * ulp(rv);
- rv += adj;
+ adj = aadj1 * ulp(dval(rv));
+ dval(rv) += adj;
#endif
}
z = word0(rv) & Exp_mask;
@@ -1719,7 +1767,7 @@ retfree:
ret:
if (se)
*se = (char *)s;
- return sign ? -rv : rv;
+ return sign ? -dval(rv) : dval(rv);
}
static PRInt32
@@ -1952,9 +2000,9 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
}
#endif
#ifdef IBM
- d += 0; /* normalize */
+ dval(d) += 0; /* normalize */
#endif
- if (!d) {
+ if (!dval(d)) {
*decpt = 1;
if (bufsize < 2) {
PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
@@ -1968,18 +2016,18 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
return PR_SUCCESS;
}
- b = d2b(d, &be, &bbits);
+ b = d2b(dval(d), &be, &bbits);
#ifdef Sudden_Underflow
i = (PRInt32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
#else
if ((i = (PRInt32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
#endif
- d2 = d;
+ dval(d2) = dval(d);
word0(d2) &= Frac_mask1;
word0(d2) |= Exp_11;
#ifdef IBM
if (j = 11 - hi0bits(word0(d2) & Frac_mask))
- d2 /= 1 << j;
+ dval(d2) /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5
@@ -2018,19 +2066,19 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
i = bbits + be + (Bias + (P-1) - 1);
x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
: word1(d) << (32 - i);
- d2 = x;
+ dval(d2) = x;
word0(d2) -= 31*Exp_msk1; /* adjust exponent */
i -= (Bias + (P-1) - 1) + 1;
denorm = 1;
}
#endif
- ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
k = (PRInt32)ds;
if (ds < 0. && ds != k)
k--; /* want k = floor(ds) */
k_check = 1;
if (k >= 0 && k <= Ten_pmax) {
- if (d < tens[k])
+ if (dval(d) < tens[k])
k--;
k_check = 0;
}
@@ -2097,7 +2145,7 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
/* Try to get by with floating-point arithmetic. */
i = 0;
- d2 = d;
+ dval(d2) = dval(d);
k0 = k;
ilim0 = ilim;
ieps = 2; /* conservative */
@@ -2107,7 +2155,7 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
if (j & Bletch) {
/* prevent overflows */
j &= Bletch - 1;
- d /= bigtens[n_bigtens-1];
+ dval(d) /= bigtens[n_bigtens-1];
ieps++;
}
for(; j; j >>= 1, i++)
@@ -2115,32 +2163,32 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
ieps++;
ds *= bigtens[i];
}
- d /= ds;
+ dval(d) /= ds;
}
else if ((j1 = -k) != 0) {
- d *= tens[j1 & 0xf];
+ dval(d) *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) {
ieps++;
- d *= bigtens[i];
+ dval(d) *= bigtens[i];
}
}
- if (k_check && d < 1. && ilim > 0) {
+ if (k_check && dval(d) < 1. && ilim > 0) {
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
- d *= 10.;
+ dval(d) *= 10.;
ieps++;
}
- eps = ieps*d + 7.;
+ dval(eps) = ieps*dval(d) + 7.;
word0(eps) -= (P-1)*Exp_msk1;
if (ilim == 0) {
S = mhi = 0;
- d -= 5.;
- if (d > eps)
+ dval(d) -= 5.;
+ if (dval(d) > dval(eps))
goto one_digit;
- if (d < -eps)
+ if (dval(d) < -dval(eps))
goto no_digits;
goto fast_failed;
}
@@ -2149,33 +2197,33 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
/* Use Steele & White method of only
* generating digits needed.
*/
- eps = 0.5/tens[ilim-1] - eps;
+ dval(eps) = 0.5/tens[ilim-1] - dval(eps);
for(i = 0;;) {
- L = (Long) d;
- d -= L;
+ L = (Long) (dval(d));
+ dval(d) -= L;
*s++ = '0' + (PRInt32)L;
- if (d < eps)
+ if (dval(d) < dval(eps))
goto ret1;
- if (1. - d < eps)
+ if (1. - dval(d) < dval(eps))
goto bump_up;
if (++i >= ilim)
break;
- eps *= 10.;
- d *= 10.;
+ dval(eps) *= 10.;
+ dval(d) *= 10.;
}
}
else {
#endif
/* Generate ilim digits, then fix them up. */
- eps *= tens[ilim-1];
- for(i = 1;; i++, d *= 10.) {
- L = (Long) d;
- d -= L;
+ dval(eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(d) *= 10.) {
+ L = (Long) (dval(d));
+ dval(d) -= L;
*s++ = '0' + (PRInt32)L;
if (i == ilim) {
- if (d > 0.5 + eps)
+ if (dval(d) > 0.5 + dval(eps))
goto bump_up;
- else if (d < 0.5 - eps) {
+ else if (dval(d) < 0.5 - dval(eps)) {
while(*--s == '0'){} /* just count -- nothing to execute */
s++;
goto ret1;
@@ -2188,7 +2236,7 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
#endif
fast_failed:
s = s0;
- d = d2;
+ dval(d) = dval(d2);
k = k0;
ilim = ilim0;
}
@@ -2200,24 +2248,24 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
ds = tens[k];
if (ndigits < 0 && ilim <= 0) {
S = mhi = 0;
- if (ilim < 0 || d <= 5*ds)
+ if (ilim < 0 || dval(d) <= 5*ds)
goto no_digits;
goto one_digit;
}
for(i = 1;; i++) {
- L = (Long) (d / ds);
- d -= L*ds;
+ 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 (d < 0) {
+ if (dval(d) < 0) {
L--;
- d += ds;
+ dval(d) += ds;
}
#endif
*s++ = '0' + (PRInt32)L;
if (i == ilim) {
- d += d;
- if ((d > ds) || (d == ds && L & 1)) {
+ dval(d) += dval(d);
+ if ((dval(d) > ds) || (dval(d) == ds && L & 1)) {
bump_up:
while(*--s == '9')
if (s == s0) {
@@ -2229,7 +2277,7 @@ PR_dtoa(PRFloat64 d, int mode, int ndigits,
}
break;
}
- if (!(d *= 10.))
+ if (!(dval(d) *= 10.))
break;
}
goto ret1;
@@ -2514,7 +2562,7 @@ PR_cnvtf(char *buf,int bufsz, int prcsn,double fval)
return;
}
/* XXX Why use mode 1? */
- if (PR_dtoa(fval,1,prcsn,&decpt,&sign,&endnum,num,bufsz)
+ if (PR_dtoa(dval(fval),1,prcsn,&decpt,&sign,&endnum,num,bufsz)
== PR_FAILURE) {
buf[0] = '\0';
goto done;
diff --git a/pr/src/misc/prenv.c b/pr/src/misc/prenv.c
index 75af10fb..fdcfb017 100644
--- a/pr/src/misc/prenv.c
+++ b/pr/src/misc/prenv.c
@@ -59,7 +59,7 @@ static PRLock *_pr_envLock = NULL;
/************************************************************************/
-void _PR_InitEnv()
+void _PR_InitEnv(void)
{
_PR_NEW_LOCK_ENV();
}
diff --git a/pr/src/misc/prerr.c b/pr/src/misc/prerr.c
index 68bcc6ce..aaa1c38b 100644
--- a/pr/src/misc/prerr.c
+++ b/pr/src/misc/prerr.c
@@ -113,12 +113,13 @@ static const struct PRErrorMessage text[] = {
{"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_MAX_ERROR", "Placeholder for the end of the list"},
{0, 0}
};
-static const struct PRErrorTable et = { text, "prerr", -6000L, 75 };
+static const struct PRErrorTable et = { text, "prerr", -6000L, 76 };
-void nspr_InitializePRErrorTable() {
+void nspr_InitializePRErrorTable(void) {
PR_ErrorInstallTable(&et);
}
diff --git a/pr/src/misc/prerr.et b/pr/src/misc/prerr.et
index e7e21305..9281ee6e 100644
--- a/pr/src/misc/prerr.et
+++ b/pr/src/misc/prerr.et
@@ -128,6 +128,7 @@ 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_MAX_ERROR, "Placeholder for the end of the list"
diff --git a/pr/src/misc/prerr.properties b/pr/src/misc/prerr.properties
index 652545e0..f6f0db26 100644
--- a/pr/src/misc/prerr.properties
+++ b/pr/src/misc/prerr.properties
@@ -32,7 +32,6 @@
#
#
-#
# prerr.properties
# This file is automatically generated; please do not edit it.
PR_OUT_OF_MEMORY_ERROR=Memory allocation attempt failed
@@ -109,4 +108,5 @@ 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_MAX_ERROR=Placeholder for the end of the list
diff --git a/pr/src/misc/prerror.c b/pr/src/misc/prerror.c
index 8456d9d2..6e0d5f19 100644
--- a/pr/src/misc/prerror.c
+++ b/pr/src/misc/prerror.c
@@ -37,13 +37,13 @@
#include <string.h>
#include <stdlib.h>
-PR_IMPLEMENT(PRErrorCode) PR_GetError()
+PR_IMPLEMENT(PRErrorCode) PR_GetError(void)
{
PRThread *thread = PR_GetCurrentThread();
return thread->errorCode;
}
-PR_IMPLEMENT(PRInt32) PR_GetOSError()
+PR_IMPLEMENT(PRInt32) PR_GetOSError(void)
{
PRThread *thread = PR_GetCurrentThread();
return thread->osErrorCode;
diff --git a/pr/src/misc/prinit.c b/pr/src/misc/prinit.c
index 6da27fa0..04c92226 100644
--- a/pr/src/misc/prinit.c
+++ b/pr/src/misc/prinit.c
@@ -161,7 +161,7 @@ static void _pr_SetNativeThreadsOnlyMode(void)
#endif
#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
-extern PRStatus _pr_init_ipv6();
+extern PRStatus _pr_init_ipv6(void);
#endif
static void _PR_InitStuff(void)
@@ -169,6 +169,9 @@ 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
@@ -220,10 +223,6 @@ static void _PR_InitStuff(void)
_PR_InitCPUs();
#endif
-#ifdef _PR_ZONE_ALLOCATOR
- _PR_InitZones();
-#endif
-
/*
* XXX: call _PR_InitMem only on those platforms for which nspr implements
* malloc, for now.
@@ -251,7 +250,7 @@ static void _PR_InitStuff(void)
_PR_MD_FINAL_INIT();
}
-void _PR_ImplicitInitialization()
+void _PR_ImplicitInitialization(void)
{
_PR_InitStuff();
@@ -417,9 +416,10 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup()
PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0));
#endif
-#if defined(WIN16)
+ _PR_CleanupMW();
+ _PR_CleanupDtoa();
+ _PR_CleanupCallOnce();
_PR_ShutdownLinker();
-#endif
/* Release the primordial thread's private data, etc. */
_PR_CleanupThread(me);
@@ -449,7 +449,11 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup()
* Ideally, for each _PR_InitXXX(), there should be a corresponding
* _PR_XXXCleanup() that we can call here.
*/
+ _PR_CleanupNet();
_PR_CleanupIO();
+#ifdef WINNT
+ _PR_CleanupCPUs();
+#endif
_PR_CleanupThreads();
PR_DestroyLock(_pr_sleeplock);
_pr_sleeplock = NULL;
@@ -561,7 +565,7 @@ PR_ProcessAttrSetCurrentDirectory(
const char *dir)
{
PR_FREEIF(attr->currentDirectory);
- attr->currentDirectory = PR_MALLOC(strlen(dir) + 1);
+ attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1);
if (!attr->currentDirectory) {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
return PR_FAILURE;
@@ -776,13 +780,20 @@ static struct {
PRCondVar *cv;
} mod_init;
-static void _PR_InitCallOnce() {
+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,
@@ -808,6 +819,31 @@ PR_IMPLEMENT(PRStatus) PR_CallOnce(
return once->status;
}
+PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
+ PRCallOnceType *once,
+ PRCallOnceWithArgFN func,
+ void *arg)
+{
+ if (!_pr_initialized) _PR_ImplicitInitialization();
+
+ if (!once->initialized) {
+ if (PR_AtomicSet(&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);
+ }
+ }
+ return once->status;
+}
+
PRBool _PR_Obsolete(const char *obsolete, const char *preferred)
{
#if defined(DEBUG)
diff --git a/pr/src/misc/prinrval.c b/pr/src/misc/prinrval.c
index d0af3977..a319e8cb 100644
--- a/pr/src/misc/prinrval.c
+++ b/pr/src/misc/prinrval.c
@@ -68,13 +68,13 @@ void _PR_InitClock(void)
* 2) The units here are milliseconds. That's not appropriate for our use.
*/
-PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow()
+PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow(void)
{
if (!_pr_initialized) _PR_ImplicitInitialization();
return _PR_MD_GET_INTERVAL();
} /* PR_IntervalNow */
-PR_EXTERN(PRUint32) PR_TicksPerSecond()
+PR_EXTERN(PRUint32) PR_TicksPerSecond(void)
{
if (!_pr_initialized) _PR_ImplicitInitialization();
return _PR_MD_INTERVAL_PER_SEC();
diff --git a/pr/src/misc/prlong.c b/pr/src/misc/prlong.c
index df8d9e2e..31153293 100644
--- a/pr/src/misc/prlong.c
+++ b/pr/src/misc/prlong.c
@@ -37,6 +37,7 @@
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 );
#if defined(HAVE_WATCOM_BUG_2)
PRInt64 __pascal __loadds __export
@@ -45,10 +46,13 @@ PRInt64 __pascal __loadds __export
LL_MaxInt(void) { return ll_maxint; }
PRInt64 __pascal __loadds __export
LL_MinInt(void) { return ll_minint; }
+PRUint64 __pascal __loadds __export
+ LL_MaxUint(void) { return ll_maxuint; }
#else
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; }
#endif
#ifndef HAVE_LONG_LONG
diff --git a/pr/src/misc/prnetdb.c b/pr/src/misc/prnetdb.c
index b40ca804..b26b7539 100644
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -83,6 +83,12 @@ PRLock *_pr_dnsLock = NULL;
* Some return a pointer to struct protoent, others return
* an int.
*/
+#if defined(XP_BEOS) && defined(BONE_VERSION)
+#include <arpa/inet.h> /* pick up define for inet_addr */
+#include <sys/socket.h>
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_POINTER
+#endif
#if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \
|| (defined(LINUX) && defined(_REENTRANT) \
@@ -92,7 +98,7 @@ PRLock *_pr_dnsLock = NULL;
#endif
#if defined(OSF1) \
- || defined(AIX4_3) || (defined(AIX) && defined(_THREAD_SAFE)) \
+ || defined(AIX4_3_PLUS) || (defined(AIX) && defined(_THREAD_SAFE)) \
|| (defined(HPUX10_10) && defined(_REENTRANT)) \
|| (defined(HPUX10_20) && defined(_REENTRANT))
#define _PR_HAVE_GETPROTO_R
@@ -157,6 +163,250 @@ const PRIPv6Addr _pr_in6addr_loopback = {{{ 0, 0, 0, 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(MACOS_DEPLOYMENT_TARGET) \
+ && MACOS_DEPLOYMENT_TARGET < 100200)))
+
+/*
+ * Use SIOCGIFCONF ioctl on platforms that don't have routing
+ * sockets. Warning: whether SIOCGIFCONF ioctl returns AF_INET6
+ * network interfaces is not portable.
+ *
+ * The _pr_QueryNetIfs() function is derived from the code in
+ * src/lib/libc/net/getifaddrs.c in BSD Unix and the code in
+ * Section 16.6 of W. Richard Stevens' Unix Network Programming,
+ * Vol. 1, 2nd. Ed.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+
+#ifdef DEBUG_QUERY_IFS
+static void
+_pr_PrintIfreq(struct ifreq *ifr)
+{
+ PRNetAddr addr;
+ struct sockaddr *sa;
+ const char* family;
+ char addrstr[64];
+
+ sa = &ifr->ifr_addr;
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ family = "inet";
+ memcpy(&addr.inet.ip, &sin->sin_addr, sizeof(sin->sin_addr));
+ } else if (sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+ family = "inet6";
+ memcpy(&addr.ipv6.ip, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
+ } else {
+ return; /* skip if not AF_INET or AF_INET6 */
+ }
+ addr.raw.family = sa->sa_family;
+ PR_NetAddrToString(&addr, addrstr, sizeof(addrstr));
+ printf("%s: %s %s\n", ifr->ifr_name, family, addrstr);
+}
+#endif
+
+static void
+_pr_QueryNetIfs(void)
+{
+ int sock;
+ int rv;
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ struct ifreq *lifr;
+ PRUint32 len, lastlen;
+ char *buf;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+ return;
+ }
+
+ /* Issue SIOCGIFCONF request in a loop. */
+ lastlen = 0;
+ len = 100 * sizeof(struct ifreq); /* initial buffer size guess */
+ for (;;) {
+ buf = (char *)PR_Malloc(len);
+ if (NULL == buf) {
+ close(sock);
+ return;
+ }
+ ifc.ifc_buf = buf;
+ ifc.ifc_len = len;
+ rv = ioctl(sock, SIOCGIFCONF, &ifc);
+ if (rv < 0) {
+ if (errno != EINVAL || lastlen != 0) {
+ close(sock);
+ PR_Free(buf);
+ return;
+ }
+ } else {
+ if (ifc.ifc_len == lastlen)
+ break; /* success, len has not changed */
+ lastlen = ifc.ifc_len;
+ }
+ len += 10 * sizeof(struct ifreq); /* increment */
+ PR_Free(buf);
+ }
+ close(sock);
+
+ ifr = ifc.ifc_req;
+ lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
+
+ while (ifr < lifr) {
+ struct sockaddr *sa;
+ int sa_len;
+
+#ifdef DEBUG_QUERY_IFS
+ _pr_PrintIfreq(ifr);
+#endif
+ sa = &ifr->ifr_addr;
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+ if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+ _pr_have_inet_if = PR_TRUE;
+ }
+ } else if (sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+ if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
+ && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ _pr_have_inet6_if = PR_TRUE;
+ }
+ }
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ sa_len = PR_MAX(sa->sa_len, sizeof(struct sockaddr));
+#else
+ switch (sa->sa_family) {
+#ifdef AF_LINK
+ case AF_LINK:
+ sa_len = sizeof(struct sockaddr_dl);
+ break;
+#endif
+ case AF_INET6:
+ sa_len = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ sa_len = sizeof(struct sockaddr);
+ break;
+ }
+#endif
+ ifr = (struct ifreq *)(((char *)sa) + sa_len);
+ }
+ PR_Free(buf);
+}
+
+#elif (defined(DARWIN) && defined(HAVE_GETIFADDRS)) || defined(FREEBSD) \
+ || defined(NETBSD) || defined(OPENBSD)
+
+/*
+ * Use the BSD getifaddrs function.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+
+#ifdef DEBUG_QUERY_IFS
+static void
+_pr_PrintIfaddrs(struct ifaddrs *ifa)
+{
+ struct sockaddr *sa;
+ const char* family;
+ void *addrp;
+ char addrstr[64];
+
+ sa = ifa->ifa_addr;
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ family = "inet";
+ addrp = &sin->sin_addr;
+ } else if (sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+ family = "inet6";
+ addrp = &sin6->sin6_addr;
+ } else {
+ return; /* skip if not AF_INET or AF_INET6 */
+ }
+ inet_ntop(sa->sa_family, addrp, addrstr, sizeof(addrstr));
+ printf("%s: %s %s\n", ifa->ifa_name, family, addrstr);
+}
+#endif
+
+static void
+_pr_QueryNetIfs(void)
+{
+ struct ifaddrs *ifp;
+ struct ifaddrs *ifa;
+
+ if (getifaddrs(&ifp) == -1) {
+ return;
+ }
+ for (ifa = ifp; ifa; ifa = ifa->ifa_next) {
+ struct sockaddr *sa;
+
+#ifdef DEBUG_QUERY_IFS
+ _pr_PrintIfaddrs(ifa);
+#endif
+ sa = ifa->ifa_addr;
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+ if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+ _pr_have_inet_if = 1;
+ }
+ } else if (sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+ if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
+ && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ _pr_have_inet6_if = 1;
+ }
+ }
+ }
+ freeifaddrs(ifp);
+}
+
+#else /* default */
+
+/*
+ * Emulate the code in NSPR 4.2 or older. PR_GetIPNodeByName behaves
+ * as if the system had both IPv4 and IPv6 source addresses configured.
+ */
+static void
+_pr_QueryNetIfs(void)
+{
+ _pr_have_inet_if = PR_TRUE;
+ _pr_have_inet6_if = PR_TRUE;
+}
+
+#endif
+
+#endif /* _PR_INET6 && _PR_HAVE_GETHOSTBYNAME2 */
+
void _PR_InitNet(void)
{
#if defined(XP_UNIX)
@@ -174,6 +424,31 @@ void _PR_InitNet(void)
#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
}
/*
@@ -215,7 +490,6 @@ static void MakeIPv4MappedAddr(const char *v4, char *v6)
memset(v6, 0, 10);
memset(v6 + 10, 0xff, 2);
memcpy(v6 + 12, v4, 4);
- PR_ASSERT(_PR_IN6_IS_ADDR_V4MAPPED(((PRIPv6Addr *) v6)));
}
/*
@@ -225,7 +499,6 @@ static void MakeIPv4CompatAddr(const char *v4, char *v6)
{
memset(v6, 0, 12);
memcpy(v6 + 12, v4, 4);
- PR_ASSERT(_PR_IN6_IS_ADDR_V4COMPAT(((PRIPv6Addr *) v6)));
}
/*
@@ -406,7 +679,7 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName(
tmpbuf = localbuf;
if (bufsize > sizeof(localbuf))
{
- tmpbuf = PR_Malloc(bufsize);
+ tmpbuf = (char *)PR_Malloc(bufsize);
if (NULL == tmpbuf)
{
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
@@ -442,15 +715,51 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName(
return rv;
}
-#if defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+#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 *);
-extern void * _pr_getipnodebyname_fp;
-extern void * _pr_getipnodebyaddr_fp;
-extern void * _pr_freehostent_fp;
+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;
+#if defined(VMS)
+#define GETIPNODEBYNAME getenv("GETIPNODEBYNAME")
+#define GETIPNODEBYADDR getenv("GETIPNODEBYADDR")
+#define FREEHOSTENT getenv("FREEHOSTENT")
+#else
+#define GETIPNODEBYNAME "getipnodebyname"
+#define GETIPNODEBYADDR "getipnodebyaddr"
+#define FREEHOSTENT "freehostent"
+#endif
+ _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)
@@ -521,6 +830,25 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
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;
@@ -538,7 +866,7 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
tmpbuf = localbuf;
if (bufsize > sizeof(localbuf))
{
- tmpbuf = PR_Malloc(bufsize);
+ tmpbuf = (char *)PR_Malloc(bufsize);
if (NULL == tmpbuf)
{
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
@@ -553,11 +881,15 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
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 == PR_TRUE)
+ if (_pr_ipv6_is_present == PR_TRUE)
#endif
- h = GETHOSTBYNAME2(name, AF_INET6);
- if ((NULL == h) && (flags & PR_AI_V4MAPPED))
+ 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);
@@ -565,8 +897,11 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
}
else
{
- did_af_inet = PR_TRUE;
- h = GETHOSTBYNAME2(name, af);
+ 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);
@@ -575,7 +910,12 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
#endif /* _PR_HAVE_GETHOSTBYNAME2 */
#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
if (_pr_ipv6_is_present == PR_TRUE)
+ {
+#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();
@@ -619,7 +959,8 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
#endif
#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED)
- && (flags & (PR_AI_ALL|PR_AI_ADDRCONFIG))
+ && ((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)
@@ -634,8 +975,12 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
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 == PR_FALSE)
UNLOCK_DNS();
+#endif
#else /* _PR_INET6 */
UNLOCK_DNS();
#endif /* _PR_INET6 */
@@ -681,6 +1026,10 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
#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
{
@@ -717,7 +1066,7 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
tmpbuf = localbuf;
if (bufsize > sizeof(localbuf))
{
- tmpbuf = PR_Malloc(bufsize);
+ tmpbuf = (char *)PR_Malloc(bufsize);
if (NULL == tmpbuf)
{
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
@@ -731,8 +1080,13 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
h = getipnodebyaddr(addr, addrlen, af, &error_num);
#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)
if (_pr_ipv6_is_present == PR_TRUE)
+ {
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+ LOCK_DNS();
+#endif
h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen,
af, &error_num);
+ }
else
{
LOCK_DNS();
@@ -788,8 +1142,12 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
/* 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 == PR_FALSE)
UNLOCK_DNS();
+#endif
#else /* _PR_HAVE_GETIPNODEBYADDR */
UNLOCK_DNS();
#endif /* _PR_HAVE_GETIPNODEBYADDR */
@@ -1015,7 +1373,7 @@ PRUintn _PR_NetAddrSize(const PRNetAddr* addr)
#else
addrsize = sizeof(addr->ipv6);
#endif
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) || defined(XP_OS2)
else if (AF_UNIX == addr->raw.family)
addrsize = sizeof(addr->local);
#endif
@@ -1164,7 +1522,7 @@ PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
return PR_FALSE;
}
-#ifndef _PR_INET6
+#ifndef _PR_HAVE_INET_NTOP
#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,
@@ -1404,14 +1762,14 @@ static const char *V6AddrToString(
#undef STUFF
}
-#endif /* !_PR_INET6 */
+#endif /* !_PR_HAVE_INET_NTOP */
PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
{
PRStatus status = PR_SUCCESS;
PRIntn rv;
-#if defined(_PR_INET6)
+#if defined(_PR_HAVE_INET_NTOP)
rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
if (1 == rv)
{
@@ -1434,7 +1792,7 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
status = PR_FAILURE;
}
}
-#else /* _PR_INET6 */
+#else /* _PR_HAVE_INET_NTOP */
rv = StringToV6Addr(string, &addr->ipv6.ip);
if (1 == rv) {
addr->raw.family = PR_AF_INET6;
@@ -1458,7 +1816,7 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
status = PR_FAILURE;
}
-#endif /* _PR_INET6 */
+#endif /* _PR_HAVE_INET_NTOP */
return status;
}
@@ -1468,7 +1826,7 @@ PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
{
if (PR_AF_INET6 == addr->raw.family)
{
-#if defined(_PR_INET6)
+#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))
@@ -1554,3 +1912,268 @@ PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
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
+
+#elif defined(_PR_INET6_PROBE)
+
+typedef struct addrinfo PRADDRINFO;
+
+/* getaddrinfo/freeaddrinfo 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);
+
+/* global state */
+static FN_GETADDRINFO _pr_getaddrinfo = NULL;
+static FN_FREEADDRINFO _pr_freeaddrinfo = NULL;
+
+#if defined(VMS)
+#define GETADDRINFO_SYMBOL getenv("GETADDRINFO")
+#define FREEADDRINFO_SYMBOL getenv("FREEADDRINFO")
+#else
+#define GETADDRINFO_SYMBOL "getaddrinfo"
+#define FREEADDRINFO_SYMBOL "freeaddrinfo"
+#endif
+
+PRStatus
+_pr_find_getaddrinfo(void)
+{
+ PRLibrary *lib;
+#ifdef WIN32
+ /*
+ * On windows, we need to search ws2_32.dll for getaddrinfo and
+ * freeaddrinfo. This library might not be loaded yet.
+ */
+ lib = PR_LoadLibrary("ws2_32.dll");
+ if (!lib) {
+ return PR_FAILURE;
+ }
+ _pr_getaddrinfo = (FN_GETADDRINFO)
+ PR_FindFunctionSymbol(lib, GETADDRINFO_SYMBOL);
+ _pr_freeaddrinfo = (FN_FREEADDRINFO)
+ PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL);
+ if (!_pr_getaddrinfo || !_pr_freeaddrinfo) {
+ PR_UnloadLibrary(lib);
+ return PR_FAILURE;
+ }
+ /* Keep ws2_32.dll loaded. */
+ return PR_SUCCESS;
+#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_UnloadLibrary(lib);
+ if (!_pr_freeaddrinfo) {
+ return PR_FAILURE;
+ }
+ return PR_SUCCESS;
+#endif
+}
+
+#define GETADDRINFO (*_pr_getaddrinfo)
+#define FREEADDRINFO (*_pr_freeaddrinfo)
+
+#endif /* _PR_INET6 */
+
+#endif /* _PR_HAVE_GETADDRINFO */
+
+/*
+ * 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;
+} 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;
+ }
+ return (PRAddrInfo *) ai;
+}
+
+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_ADDRCONFIG) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return NULL;
+ }
+
+ if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if !defined(_PR_HAVE_GETADDRINFO)
+ return pr_GetAddrInfoByNameFB(hostname, af, flags);
+#else
+#if defined(_PR_INET6_PROBE)
+ if (!_pr_ipv6_is_present) {
+ return pr_GetAddrInfoByNameFB(hostname, af, flags);
+ }
+#endif
+ {
+ PRADDRINFO *res, hints;
+ PRStatus rv;
+
+ /*
+ * we assume a RFC 2553 compliant getaddrinfo. this may at some
+ * point need to be customized as platforms begin to adopt the
+ * RFC 3493.
+ */
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC;
+
+ /*
+ * it is important to select a socket type in the hints, otherwise we
+ * will get back repetitive entries: one for each socket type. since
+ * we do not expose ai_socktype through our API, it is okay to do this
+ * here. the application may still choose to create a socket of some
+ * other type.
+ */
+ hints.ai_socktype = SOCK_STREAM;
+
+ rv = GETADDRINFO(hostname, NULL, &hints, &res);
+ if (rv == 0)
+ return (PRAddrInfo *) res;
+
+ PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv);
+ }
+ return NULL;
+#endif
+}
+
+PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+#if defined(_PR_INET6_PROBE)
+ if (!_pr_ipv6_is_present)
+ PR_Free((PRAddrInfoFB *) ai);
+ else
+#endif
+ FREEADDRINFO((PRADDRINFO *) ai);
+#else
+ PR_Free((PRAddrInfoFB *) ai);
+#endif
+}
+
+PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void *iterPtr,
+ const PRAddrInfo *base,
+ PRUint16 port,
+ PRNetAddr *result)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+ PRADDRINFO *ai;
+#if defined(_PR_INET6_PROBE)
+ if (!_pr_ipv6_is_present) {
+ /* using PRAddrInfoFB */
+ PRIntn iter = (PRIntn) iterPtr;
+ iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result);
+ if (iter < 0)
+ iter = 0;
+ return (void *) iter;
+ }
+#endif
+
+ if (iterPtr)
+ ai = ((PRADDRINFO *) iterPtr)->ai_next;
+ else
+ ai = (PRADDRINFO *) base;
+
+ if (ai) {
+ /* copy sockaddr to PRNetAddr */
+ memcpy(result, ai->ai_addr, ai->ai_addrlen);
+ result->raw.family = ai->ai_addr->sa_family;
+ 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)
+ return ((const PRAddrInfoFB *) ai)->hostent.h_name;
+#endif
+ return ((const PRADDRINFO *) ai)->ai_canonname;
+#else
+ return ((const PRAddrInfoFB *) ai)->hostent.h_name;
+#endif
+}
diff --git a/pr/src/misc/prolock.c b/pr/src/misc/prolock.c
index a2a50ced..e8384879 100644
--- a/pr/src/misc/prolock.c
+++ b/pr/src/misc/prolock.c
@@ -38,7 +38,6 @@
** Implement the API defined in prolock.h
**
*/
-#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
#include "prolock.h"
#include "prlog.h"
#include "prerror.h"
@@ -96,13 +95,3 @@ PR_IMPLEMENT(PRStatus)
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
return PR_FAILURE;
} /* end PR_UnlockOrderedLock() */
-
-#else /* ! defined(FORCE_NSPR_ORDERED_LOCK) */
-/*
-** NSPR Ordered Lock is not defined when !DEBUG and !FORCE_NSPR_ORDERED_LOCK
-**
-*/
-
-/* Some compilers don't like an empty compilation unit. */
-static int dummy = 0;
-#endif /* defined(FORCE_NSPR_ORDERED_LOCK */
diff --git a/pr/src/misc/prrng.c b/pr/src/misc/prrng.c
index bc6c0cd8..480b347d 100644
--- a/pr/src/misc/prrng.c
+++ b/pr/src/misc/prrng.c
@@ -34,6 +34,16 @@
#include "primpl.h"
+/*
+ * We were not including <string.h> in optimized builds. On AIX this
+ * caused libnspr4.so to export memcpy and some binaries linked with
+ * libnspr4.so resolved their memcpy references with libnspr4.so. To
+ * be backward compatible with old libnspr4.so binaries, we do not
+ * include <string.h> in optimized builds for AIX. (bug 200561)
+ */
+#if !(defined(AIX) && !defined(DEBUG))
+#include <string.h>
+#endif
PRSize _pr_CopyLowBits(
void *dst,
diff --git a/pr/src/misc/prsystem.c b/pr/src/misc/prsystem.c
index bb786766..edf5dbd0 100644
--- a/pr/src/misc/prsystem.c
+++ b/pr/src/misc/prsystem.c
@@ -58,7 +58,7 @@
#endif
#if defined(HPUX)
-#include <sys/mp.h>
+#include <sys/mpctl.h>
#endif
#if defined(XP_UNIX)
@@ -66,7 +66,7 @@
#include <sys/utsname.h>
#endif
-PR_IMPLEMENT(char) PR_GetDirectorySeparator()
+PR_IMPLEMENT(char) PR_GetDirectorySeparator(void)
{
return PR_DIRECTORY_SEPARATOR;
} /* PR_GetDirectorySeparator */
@@ -74,7 +74,7 @@ PR_IMPLEMENT(char) PR_GetDirectorySeparator()
/*
** OBSOLETE -- the function name is misspelled.
*/
-PR_IMPLEMENT(char) PR_GetDirectorySepartor()
+PR_IMPLEMENT(char) PR_GetDirectorySepartor(void)
{
#if defined(DEBUG)
static PRBool warn = PR_TRUE;
@@ -86,6 +86,11 @@ PR_IMPLEMENT(char) PR_GetDirectorySepartor()
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;
@@ -97,6 +102,12 @@ PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 bufle
case PR_SI_HOSTNAME:
if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen))
return PR_FAILURE;
+ /*
+ * 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] == '.') {
@@ -105,6 +116,7 @@ PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 bufle
}
len += 1;
}
+#endif
break;
case PR_SI_SYSNAME:
@@ -150,7 +162,6 @@ PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 bufle
default:
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
- break;
}
return PR_SUCCESS;
}
diff --git a/pr/src/misc/prtime.c b/pr/src/misc/prtime.c
index 0aa6e46c..3eae35c7 100644
--- a/pr/src/misc/prtime.c
+++ b/pr/src/misc/prtime.c
@@ -637,6 +637,7 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt)
PRTime secs64;
PRInt64 usecPerSec;
PRInt64 maxInt32;
+ PRInt64 minInt32;
PRInt32 dayOffset;
PRInt32 offset2Jan1970;
PRInt32 offsetNew;
@@ -682,9 +683,10 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt)
secs64 = PR_ImplodeTime(gmt); /* This is still in microseconds */
LL_I2L(usecPerSec, PR_USEC_PER_SEC);
LL_DIV(secs64, secs64, usecPerSec); /* Convert to seconds */
- LL_I2L(maxInt32, 0x7fffffff);
- if (LL_CMP(secs64, >, maxInt32)) {
- /* secs64 is too large for time_t (32-bit integer) */
+ 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;
@@ -774,7 +776,7 @@ PR_IMPLEMENT(PRTimeParameters)
PR_USPacificTimeParameters(const PRExplodedTime *gmt)
{
PRTimeParameters retVal;
- PRExplodedTime std;
+ PRExplodedTime st;
/*
* Based on geographic location and GMT, figure out offset of
@@ -789,32 +791,32 @@ PR_USPacificTimeParameters(const PRExplodedTime *gmt)
* is ignored.
*/
- std.tm_usec = gmt->tm_usec;
- std.tm_sec = gmt->tm_sec;
- std.tm_min = gmt->tm_min;
- std.tm_hour = gmt->tm_hour;
- std.tm_mday = gmt->tm_mday;
- std.tm_month = gmt->tm_month;
- std.tm_year = gmt->tm_year;
- std.tm_wday = gmt->tm_wday;
- std.tm_yday = gmt->tm_yday;
+ 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(&std, retVal.tp_gmt_offset);
+ ApplySecOffset(&st, retVal.tp_gmt_offset);
/*
* Apply the rules on standard time or GMT to obtain daylight saving
* time offset. In this implementation, we use the US DST rule.
*/
- if (std.tm_month < 3) {
+ if (st.tm_month < 3) {
retVal.tp_dst_offset = 0L;
- } else if (std.tm_month == 3) {
- if (std.tm_wday == 0) {
+ } else if (st.tm_month == 3) {
+ if (st.tm_wday == 0) {
/* A Sunday */
- if (std.tm_mday <= 7) {
+ if (st.tm_mday <= 7) {
/* First Sunday */
/* 01:59:59 PST -> 03:00:00 PDT */
- if (std.tm_hour < 2) {
+ if (st.tm_hour < 2) {
retVal.tp_dst_offset = 0L;
} else {
retVal.tp_dst_offset = 3600L;
@@ -825,7 +827,7 @@ PR_USPacificTimeParameters(const PRExplodedTime *gmt)
}
} else {
/* Not a Sunday. See if before first Sunday or after */
- if (std.tm_wday + 1 <= std.tm_mday) {
+ if (st.tm_wday + 1 <= st.tm_mday) {
/* After first Sunday */
retVal.tp_dst_offset = 3600L;
} else {
@@ -833,14 +835,14 @@ PR_USPacificTimeParameters(const PRExplodedTime *gmt)
retVal.tp_dst_offset = 0L;
}
}
- } else if (std.tm_month < 9) {
+ } else if (st.tm_month < 9) {
retVal.tp_dst_offset = 3600L;
- } else if (std.tm_month == 9) {
- if (std.tm_wday == 0) {
- if (31 - std.tm_mday < 7) {
+ } else if (st.tm_month == 9) {
+ if (st.tm_wday == 0) {
+ if (31 - st.tm_mday < 7) {
/* Last Sunday */
/* 01:59:59 PDT -> 01:00:00 PST */
- if (std.tm_hour < 1) {
+ if (st.tm_hour < 1) {
retVal.tp_dst_offset = 3600L;
} else {
retVal.tp_dst_offset = 0L;
@@ -851,7 +853,7 @@ PR_USPacificTimeParameters(const PRExplodedTime *gmt)
}
} else {
/* See if before or after last Sunday */
- if (7 - std.tm_wday <= 31 - std.tm_mday) {
+ if (7 - st.tm_wday <= 31 - st.tm_mday) {
/* before last Sunday */
retVal.tp_dst_offset = 3600L;
} else {
@@ -1662,15 +1664,14 @@ PR_FormatTime(char *buf, int buflen, const char *fmt, const PRExplodedTime *tm)
/*
* On some platforms, for example SunOS 4, struct tm has two additional
- * fields: tm_zone and tm_gmtoff. The following code attempts to obtain
- * values for these two fields.
+ * fields: tm_zone and tm_gmtoff.
*/
-#if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS)
- if (mktime(&a) == -1) {
- PR_snprintf(buf, buflen, "can't get timezone");
- return 0;
- }
+#if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) \
+ || defined(NETBSD) || defined(OPENBSD) || defined(FREEBSD) \
+ || defined(DARWIN)
+ a.tm_zone = NULL;
+ a.tm_gmtoff = tm->tm_params.tp_gmt_offset + tm->tm_params.tp_dst_offset;
#endif
return strftime(buf, buflen, fmt, &a);
diff --git a/pr/src/misc/prtpool.c b/pr/src/misc/prtpool.c
index 2f43c676..d0816b30 100644
--- a/pr/src/misc/prtpool.c
+++ b/pr/src/misc/prtpool.c
@@ -166,7 +166,7 @@ struct PRJob {
PR_END_MACRO
static void delete_job(PRJob *jobp);
-static PRThreadPool * alloc_threadpool();
+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);
@@ -599,11 +599,11 @@ delete_threadpool(PRThreadPool *tp)
}
static PRThreadPool *
-alloc_threadpool()
+alloc_threadpool(void)
{
PRThreadPool *tp;
- tp = PR_CALLOC(sizeof(*tp));
+ tp = (PRThreadPool *) PR_CALLOC(sizeof(*tp));
if (NULL == tp)
goto failed;
tp->jobq.lock = PR_NewLock();
diff --git a/pr/src/misc/prtrace.c b/pr/src/misc/prtrace.c
index 72b9c52d..f861557c 100644
--- a/pr/src/misc/prtrace.c
+++ b/pr/src/misc/prtrace.c
@@ -41,7 +41,6 @@
**
*/
-#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
#include <string.h>
#include "prtrace.h"
#include "prclist.h"
@@ -917,14 +916,4 @@ PR_IMPLEMENT(PRIntn)
return rc;
} /* end PR_GetTraceEntries() */
-#else /* !defined(FORCE_NSPR_TRACE) */
-/*
-** The trace facility is not defined when !DEBUG and !FORCE_NSPR_TRACE
-**
-*/
-
-/* Some compilers don't like an empty compilation unit. */
-static int dummy = 0;
-#endif /* defined(FORCE_NSPR_TRACE) */
-
/* end prtrace.c */