diff options
Diffstat (limited to 'pr/src/misc')
-rw-r--r-- | pr/src/misc/Makefile.in | 12 | ||||
-rw-r--r-- | pr/src/misc/compile-et.pl | 2 | ||||
-rw-r--r-- | pr/src/misc/pralarm.c | 4 | ||||
-rw-r--r-- | pr/src/misc/prcountr.c | 12 | ||||
-rw-r--r-- | pr/src/misc/prdtoa.c | 228 | ||||
-rw-r--r-- | pr/src/misc/prenv.c | 2 | ||||
-rw-r--r-- | pr/src/misc/prerr.c | 5 | ||||
-rw-r--r-- | pr/src/misc/prerr.et | 1 | ||||
-rw-r--r-- | pr/src/misc/prerr.properties | 2 | ||||
-rw-r--r-- | pr/src/misc/prerror.c | 4 | ||||
-rw-r--r-- | pr/src/misc/prinit.c | 56 | ||||
-rw-r--r-- | pr/src/misc/prinrval.c | 4 | ||||
-rw-r--r-- | pr/src/misc/prlong.c | 4 | ||||
-rw-r--r-- | pr/src/misc/prnetdb.c | 669 | ||||
-rw-r--r-- | pr/src/misc/prolock.c | 11 | ||||
-rw-r--r-- | pr/src/misc/prrng.c | 10 | ||||
-rw-r--r-- | pr/src/misc/prsystem.c | 19 | ||||
-rw-r--r-- | pr/src/misc/prtime.c | 67 | ||||
-rw-r--r-- | pr/src/misc/prtpool.c | 6 | ||||
-rw-r--r-- | pr/src/misc/prtrace.c | 11 |
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 */ |