X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.c;h=9d9ad5c50dc0283d066485b5ee61eb548456ff4e;hb=fe572743bdc94988ae47d8a129c5f974e72052a1;hp=a4f7828734c17e03a2c0a743d69e914100ab547d;hpb=4757a2438b123364ad98fc0cb4698e56331f713b;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.c b/pp.c index a4f7828..9d9ad5c 100644 --- a/pp.c +++ b/pp.c @@ -1560,11 +1560,13 @@ PP(pp_cos) compatibility by calling rand() but allow the user to override it. See INSTALL for details. --Andy Dougherty 15 July 1998 */ -#ifndef my_rand -# define my_rand rand -#endif -#ifndef my_srand -# define my_srand srand +/* Now it's after 5.005, and Configure supports drand48() and random(), + in addition to rand(). So the overrides should not be needed any more. + --Jarkko Hietaniemi 27 September 1998 + */ + +#ifndef HAS_DRAND48_PROTO +extern double drand48 _((void)); #endif PP(pp_rand) @@ -1578,22 +1580,10 @@ PP(pp_rand) if (value == 0.0) value = 1.0; if (!srand_called) { - (void)my_srand((unsigned)seed()); + (void)seedDrand01((Rand_seed_t)seed()); srand_called = TRUE; } -#if RANDBITS == 31 - value = my_rand() * value / 2147483648.0; -#else -#if RANDBITS == 16 - value = my_rand() * value / 65536.0; -#else -#if RANDBITS == 15 - value = my_rand() * value / 32768.0; -#else - value = my_rand() * value / (double)(((unsigned long)1) << RANDBITS); -#endif -#endif -#endif + value *= Drand01(); XPUSHn(value); RETURN; } @@ -1606,7 +1596,7 @@ PP(pp_srand) anum = seed(); else anum = POPu; - (void)my_srand((unsigned)anum); + (void)seedDrand01((Rand_seed_t)anum); srand_called = TRUE; EXTEND(SP, 1); RETPUSHYES; @@ -1619,9 +1609,9 @@ seed(void) * This is really just a quick hack which grabs various garbage * values. It really should be a real hash algorithm which * spreads the effect of every input bit onto every output bit, - * if someone who knows about such tings would bother to write it. + * if someone who knows about such things would bother to write it. * Might be a good idea to add that function to CORE as well. - * No numbers below come from careful analysis or anyting here, + * No numbers below come from careful analysis or anything here, * except they are primes and SEED_C1 > 1E6 to get a full-width * value from (tv_sec * SEED_C1 + tv_usec). The multipliers should * probably be bigger too. @@ -1638,21 +1628,50 @@ seed(void) #define SEED_C5 26107 dTHR; +#ifndef PERL_NO_DEV_RANDOM + int fd; +#endif U32 u; #ifdef VMS # include /* when[] = (low 32 bits, high 32 bits) of time since epoch * in 100-ns units, typically incremented ever 10 ms. */ unsigned int when[2]; +#else +# ifdef HAS_GETTIMEOFDAY + struct timeval when; +# else + Time_t when; +# endif +#endif + +/* This test is an escape hatch, this symbol isn't set by Configure. */ +#ifndef PERL_NO_DEV_RANDOM +#ifndef PERL_RANDOM_DEVICE + /* /dev/random isn't used by default because reads from it will block + * if there isn't enough entropy available. You can compile with + * PERL_RANDOM_DEVICE to it if you'd prefer Perl to block until there + * is enough real entropy to fill the seed. */ +# define PERL_RANDOM_DEVICE "/dev/urandom" +#endif + fd = PerlLIO_open(PERL_RANDOM_DEVICE, 0); + if (fd != -1) { + if (PerlLIO_read(fd, &u, sizeof u) != sizeof u) + u = 0; + PerlLIO_close(fd); + if (u) + return u; + } +#endif + +#ifdef VMS _ckvmssts(sys$gettim(when)); u = (U32)SEED_C1 * when[0] + (U32)SEED_C2 * when[1]; #else # ifdef HAS_GETTIMEOFDAY - struct timeval when; gettimeofday(&when,(struct timezone *) 0); u = (U32)SEED_C1 * when.tv_sec + (U32)SEED_C2 * when.tv_usec; # else - Time_t when; (void)time(&when); u = (U32)SEED_C1 * when; # endif @@ -3397,7 +3416,10 @@ PP(pp_unpack) while (len-- > 0 && s < strend) { auint = utf8_to_uv((U8*)s, &along); s += along; - culong += auint; + if (checksum > 32) + cdouble += (double)auint; + else + culong += auint; } } else { @@ -3798,7 +3820,7 @@ PP(pp_unpack) char hunk[4]; hunk[3] = '\0'; - len = (*s++ - ' ') & 077; + len = uudmap[*s++] & 077; while (len > 0) { if (s < strend && ISUUCHAR(*s)) a = uudmap[*s++] & 077; @@ -3833,7 +3855,7 @@ PP(pp_unpack) if (checksum) { sv = NEWSV(42, 0); if (strchr("fFdD", datumtype) || - (checksum > 32 && strchr("iIlLN", datumtype)) ) { + (checksum > 32 && strchr("iIlLNU", datumtype)) ) { double trouble; adouble = 1.0;