X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..e07eda1a0324f771bb1ed20ef94f3229005ee46c:/stdlib/FreeBSD/random.c?ds=inline diff --git a/stdlib/FreeBSD/random.c b/stdlib/FreeBSD/random.c index e5b587e..1ca75ed 100644 --- a/stdlib/FreeBSD/random.c +++ b/stdlib/FreeBSD/random.c @@ -10,10 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,11 +31,21 @@ static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.22 2003/02/04 11:24:08 ache Exp $"); +__FBSDID("$FreeBSD$"); +#ifdef __APPLE__ +// Always compile with __DARWIN_UNIX03=1 prototypes. +// Applications using legacy interfaces (i386 only) use types of the same size: +// sizeof(int) == sizeof(long) == sizeof(size_t) +#undef __DARWIN_UNIX03 +#define __DARWIN_UNIX03 1 +#endif // __APPLE__ + +#include "namespace.h" #include "namespace.h" #include /* for srandomdev() */ #include /* for srandomdev() */ +#include #include #include #include /* for srandomdev() */ @@ -61,10 +67,10 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.22 2003/02/04 11:24:08 ache * congruential generator. If the amount of state information is less than * 32 bytes, a simple linear congruential R.N.G. is used. * - * Internally, the state information is treated as an array of longs; the + * Internally, the state information is treated as an array of uint32_t's; the * zeroeth element of the array is the type of R.N.G. being used (small * integer); the remainder of the array is the state information for the - * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of + * R.N.G. Thus, 32 bytes of state information will give 7 ints worth of * state information, which will allow a degree seven polynomial. (Note: * the zeroeth word of state information also has some other information * stored in it -- see setstate() for details). @@ -142,10 +148,14 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.22 2003/02/04 11:24:08 ache */ #define MAX_TYPES 5 /* max number of types above */ -#define NSHUFF 100 /* to drop part of seed -> 1st value correlation */ +#ifdef USE_WEAK_SEEDING +#define NSHUFF 0 +#else /* !USE_WEAK_SEEDING */ +#define NSHUFF 50 /* to drop some "seed -> 1st value" linearity */ +#endif /* !USE_WEAK_SEEDING */ -static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; -static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; +static const int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; +static const int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; /* * Initially, everything is set up as if from: @@ -161,7 +171,7 @@ static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. */ -static long randtbl[DEG_3 + 1] = { +static uint32_t randtbl[DEG_3 + 1] = { TYPE_3, #ifdef USE_WEAK_SEEDING /* Historic implementation compatibility */ @@ -196,8 +206,8 @@ static long randtbl[DEG_3 + 1] = { * in the initialization of randtbl) because the state table pointer is set * to point to randtbl[1] (as explained below). */ -static long *fptr = &randtbl[SEP_3 + 1]; -static long *rptr = &randtbl[1]; +static uint32_t *fptr = &randtbl[SEP_3 + 1]; +static uint32_t *rptr = &randtbl[1]; /* * The following things are the pointer to the state information table, the @@ -209,16 +219,14 @@ static long *rptr = &randtbl[1]; * this is more efficient than indexing every time to find the address of * the last element to see if the front and rear pointers have wrapped. */ -static long *state = &randtbl[1]; -static long rand_type = TYPE_3; -static long rand_deg = DEG_3; -static long rand_sep = SEP_3; -static long *end_ptr = &randtbl[DEG_3 + 1]; - -static inline long good_rand(long); - -static inline long good_rand (x) - long x; +static uint32_t *state = &randtbl[1]; +static int rand_type = TYPE_3; +static int rand_deg = DEG_3; +static int rand_sep = SEP_3; +static uint32_t *end_ptr = &randtbl[DEG_3 + 1]; + +static inline uint32_t +good_rand(int32_t x) { #ifdef USE_WEAK_SEEDING /* @@ -236,7 +244,7 @@ static inline long good_rand (x) * Park and Miller, Communications of the ACM, vol. 31, no. 10, * October 1988, p. 1195. */ - long hi, lo; + int32_t hi, lo; /* Can't be initialized with 0, so use another value. */ if (x == 0) @@ -263,12 +271,15 @@ static inline long good_rand (x) * for default usage relies on values produced by this routine. */ void -srandom(x) - unsigned long x; +#ifdef __APPLE__ +srandom(unsigned int x) +#else +srandom(unsigned long x) +#endif { - long i, lim; + int i, lim; - state[0] = x; + state[0] = (uint32_t)x; if (rand_type == TYPE_0) lim = NSHUFF; else { @@ -294,7 +305,7 @@ srandom(x) * a fixed seed. */ void -srandomdev() +srandomdev(void) { int fd, done; size_t len; @@ -305,7 +316,7 @@ srandomdev() len = rand_deg * sizeof state[0]; done = 0; - fd = _open("/dev/random", O_RDONLY, 0); + fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { if (_read(fd, (void *) state, len) == (ssize_t) len) done = 1; @@ -314,10 +325,9 @@ srandomdev() if (!done) { struct timeval tv; - unsigned long junk; gettimeofday(&tv, NULL); - srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk); + srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec); return; } @@ -346,18 +356,19 @@ srandomdev() * * Returns a pointer to the old state. * - * Note: The Sparc platform requires that arg_state begin on a long + * Note: The Sparc platform requires that arg_state begin on an int * word boundary; otherwise a bus error will occur. Even so, lint will * complain about mis-alignment, but you should disregard these messages. */ char * -initstate(seed, arg_state, n) - unsigned long seed; /* seed for R.N.G. */ - char *arg_state; /* pointer to state array */ - long n; /* # bytes of state info */ +#ifdef __APPLE__ +initstate(unsigned int seed, char *arg_state, size_t n) +#else +initstate(unsigned long seed, char *arg_state, long n) +#endif { char *ostate = (char *)(&state[-1]); - long *long_arg_state = (long *) arg_state; + uint32_t *int_arg_state = (uint32_t *)arg_state; if (rand_type == TYPE_0) state[-1] = rand_type; @@ -366,7 +377,7 @@ initstate(seed, arg_state, n) if (n < BREAK_0) { (void)fprintf(stderr, "random: not enough state (%ld bytes); ignored.\n", n); - return(0); + return (0); } if (n < BREAK_1) { rand_type = TYPE_0; @@ -389,14 +400,14 @@ initstate(seed, arg_state, n) rand_deg = DEG_4; rand_sep = SEP_4; } - state = (long *) (long_arg_state + 1); /* first location */ + state = int_arg_state + 1; /* first location */ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ srandom(seed); if (rand_type == TYPE_0) - long_arg_state[0] = rand_type; + int_arg_state[0] = rand_type; else - long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type; - return(ostate); + int_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type; + return (ostate); } /* @@ -414,17 +425,16 @@ initstate(seed, arg_state, n) * * Returns a pointer to the old state information. * - * Note: The Sparc platform requires that arg_state begin on a long + * Note: The Sparc platform requires that arg_state begin on an int * word boundary; otherwise a bus error will occur. Even so, lint will * complain about mis-alignment, but you should disregard these messages. */ char * -setstate(arg_state) - char *arg_state; /* pointer to state array */ +setstate(const char *arg_state) { - long *new_state = (long *) arg_state; - long type = new_state[0] % MAX_TYPES; - long rear = new_state[0] / MAX_TYPES; + uint32_t *new_state = (uint32_t *)arg_state; + uint32_t type = new_state[0] % MAX_TYPES; + uint32_t rear = new_state[0] / MAX_TYPES; char *ostate = (char *)(&state[-1]); if (rand_type == TYPE_0) @@ -445,13 +455,13 @@ setstate(arg_state) (void)fprintf(stderr, "random: state info corrupted; not changed.\n"); } - state = (long *) (new_state + 1); + state = new_state + 1; if (rand_type != TYPE_0) { rptr = &state[rear]; fptr = &state[(rear + rand_sep) % rand_deg]; } end_ptr = &state[rand_deg]; /* set end_ptr too */ - return(ostate); + return (ostate); } /* @@ -472,10 +482,10 @@ setstate(arg_state) * Returns a 31-bit random number. */ long -random() +random(void) { - long i; - long *f, *r; + uint32_t i; + uint32_t *f, *r; if (rand_type == TYPE_0) { i = state[0]; @@ -497,5 +507,5 @@ random() fptr = f; rptr = r; } - return(i); + return ((long)i); }