Improved seed() generation

Drop support for CLOCK_SGI_CYCLE.

Improved seed() generation.  Improved some comments in seed.c.
Added have_environ.c to build have_environ.h in order to
determine if:

    extern char **environ;	/* user environment */

is an valid external symbol.
This commit is contained in:
Landon Curt Noll
2021-12-06 21:16:08 -08:00
parent 7417f2e776
commit b30c5c1855
7 changed files with 213 additions and 74 deletions

1
.gitignore vendored
View File

@@ -35,6 +35,7 @@ endian_calc.h
fposval.h fposval.h
have_ban_pragma.h have_ban_pragma.h
have_const.h have_const.h
have_environ.h
have_fpos.h have_fpos.h
have_fpos_pos.h have_fpos_pos.h
have_getpgid.h have_getpgid.h

View File

@@ -3,6 +3,7 @@ The following are the changes from calc version 2.14.0.11 to date:
Fixed a number of typos. Fixed a number of typos.
Drop support for SunOS, IRIX and MINGW32_NT-5.0 targets. Drop support for SunOS, IRIX and MINGW32_NT-5.0 targets.
Drop support for CLOCK_SGI_CYCLE.
Minor improvement of various help files. Made format of help Minor improvement of various help files. Made format of help
files more consistent. files more consistent.
@@ -10,6 +11,14 @@ The following are the changes from calc version 2.14.0.11 to date:
Corrected a few comments in zrandom.c, including a case where Corrected a few comments in zrandom.c, including a case where
the comment referred to 1007 when it should have used 2^32. the comment referred to 1007 when it should have used 2^32.
Improved seed() generation. Improved some comments in seed.c.
Added have_environ.c to build have_environ.h in order to
determine if:
extern char **environ; /* user environment */
is an valid external symbol.
The following are the changes from calc version 2.14.0.9 to 2.14.0.10: The following are the changes from calc version 2.14.0.9 to 2.14.0.10:

View File

@@ -379,6 +379,19 @@ HAVE_CONST=
HAVE_UID_T= HAVE_UID_T=
#HAVE_UID_T= -DHAVE_NO_UID_T #HAVE_UID_T= -DHAVE_NO_UID_T
# Determine if we have user environment external:
#
# extern char **environ;
#
# If HAVE_ENVIRON is empty, this Makefile will run the have_environ program
# to determine if environ exsuts. If HAVE_ENVIRON is set to -DHAVE_NO_ENVIRON,
# then calc will assume there is no external environ symbol.
#
# If in doubt, leave HAVE_ENVIRON empty and this Makefile will figure it out.
#
HAVE_ENVIRON=
#HAVE_ENVIRON= -DHAVE_NO_ENVIRON
# Determine if we have memcpy(), memset() and strchr() # Determine if we have memcpy(), memset() and strchr()
# #
# If HAVE_NEWSTR is empty, this Makefile will run the have_newstr program # If HAVE_NEWSTR is empty, this Makefile will run the have_newstr program
@@ -1914,7 +1927,7 @@ BUILD_H_SRC= align32.h args.h calcerr.h conf.h endian_calc.h \
have_posscl.h have_rusage.h have_stdlib.h have_strdup.h \ have_posscl.h have_rusage.h have_stdlib.h have_strdup.h \
have_string.h have_strlcat.h have_strlcpy.h have_times.h \ have_string.h have_strlcat.h have_strlcpy.h have_times.h \
have_uid_t.h have_unistd.h have_unused.h have_urandom.h \ have_uid_t.h have_unistd.h have_unused.h have_urandom.h \
have_ustat.h longbits.h terminal.h have_ustat.h longbits.h terminal.h have_environ.h
# we build these .c files during the make # we build these .c files during the make
# #
@@ -1927,7 +1940,7 @@ BUILD_C_SRC= calcerr.c
UTIL_C_SRC= align32.c endian.c longbits.c have_newstr.c have_uid_t.c \ UTIL_C_SRC= align32.c endian.c longbits.c have_newstr.c have_uid_t.c \
have_const.c have_stdvs.c have_varvs.c fposval.c have_fpos.c \ have_const.c have_stdvs.c have_varvs.c fposval.c have_fpos.c \
have_fpos_pos.c have_offscl.c have_posscl.c have_memmv.c \ have_fpos_pos.c have_offscl.c have_posscl.c have_memmv.c \
have_ustat.c have_getsid.c have_getpgid.c \ have_ustat.c have_getsid.c have_getpgid.c have_environ.c \
have_gettime.c have_getprid.c have_rusage.c have_strdup.c \ have_gettime.c have_getprid.c have_rusage.c have_strdup.c \
have_unused.c have_ban_pragma.c have_strlcpy.c have_strlcat.c have_unused.c have_ban_pragma.c have_strlcpy.c have_strlcat.c
@@ -1944,7 +1957,7 @@ UTIL_MISC_SRC= calcerr_h.sed calcerr_h.awk calcerr_c.sed calcerr_c.awk \
UTIL_OBJS= endian.o longbits.o have_newstr.o have_uid_t.o \ UTIL_OBJS= endian.o longbits.o have_newstr.o have_uid_t.o \
have_const.o fposval.o have_fpos.o have_fpos_pos.o \ have_const.o fposval.o have_fpos.o have_fpos_pos.o \
try_strarg.o have_stdvs.o have_varvs.o have_posscl.o have_memmv.o \ try_strarg.o have_stdvs.o have_varvs.o have_posscl.o have_memmv.o \
have_ustat.o have_getsid.o have_getpgid.o \ have_ustat.o have_getsid.o have_getpgid.o have_environ.o \
have_gettime.o have_getprid.o ver_calc.o have_rusage.o have_strdup.o \ have_gettime.o have_getprid.o ver_calc.o have_rusage.o have_strdup.o \
have_unused.o have_ban_pragma.o have_strlcpy.o have_strlcat.o have_unused.o have_ban_pragma.o have_strlcpy.o have_strlcat.o
@@ -1961,7 +1974,7 @@ UTIL_PROGS= align32${EXT} fposval${EXT} have_uid_t${EXT} have_const${EXT} \
endian${EXT} longbits${EXT} have_newstr${EXT} have_stdvs${EXT} \ endian${EXT} longbits${EXT} have_newstr${EXT} have_stdvs${EXT} \
have_varvs${EXT} have_ustat${EXT} have_getsid${EXT} \ have_varvs${EXT} have_ustat${EXT} have_getsid${EXT} \
have_getpgid${EXT} have_gettime${EXT} have_getprid${EXT} \ have_getpgid${EXT} have_gettime${EXT} have_getprid${EXT} \
ver_calc${EXT} have_strdup${EXT} \ ver_calc${EXT} have_strdup${EXT} have_environ{EXT} \
have_unused${EXT} have_fpos${EXT} have_fpos_pos${EXT} \ have_unused${EXT} have_fpos${EXT} have_fpos_pos${EXT} \
have_offscl${EXT} have_rusage${EXT} have_ban_pragma${EXT} \ have_offscl${EXT} have_rusage${EXT} have_ban_pragma${EXT} \
have_strlcpy${EXT} have_strlcat${EXT} have_strlcpy${EXT} have_strlcat${EXT}
@@ -3248,6 +3261,47 @@ have_uid_t.h: have_uid_t.c have_unistd.h \
${TRUE}; \ ${TRUE}; \
fi fi
have_environ.h: have_environ.c \
banned.h have_ban_pragma.h ${MAKE_FILE} ${LOC_MKF}
${Q} ${RM} -f have_environ environ_tmp $@
${H} echo 'forming $@'
${Q} echo '/*' > $@
${Q} echo ' * DO NOT EDIT -- generated by the Makefile' >> $@
${Q} echo ' */' >> $@
${Q} echo '' >> $@
${Q} echo '' >> $@
${Q} echo '#if !defined(CALC_HAVE_ENVIRON_H)' >> $@
${Q} echo '#define CALC_HAVE_ENVIRON_H' >> $@
${Q} echo '' >> $@
${Q} echo '' >> $@
${Q} echo '/* do we have or want environ? */' >> $@
${Q} ${RM} -f have_environ.o have_environ${EXT}
-${Q} ${LCC} ${ICFLAGS} ${HAVE_ENVIRON} have_environ.c -c ${S} \
|| ${TRUE}
-${Q} ${LCC} ${ILDFLAGS} have_environ.o -o have_environ${EXT} ${S} \
|| ${TRUE}
-${Q} ./have_environ${EXT} > environ_tmp ${E} \
|| ${TRUE}
-${Q} if [ -s environ_tmp ]; then \
${CAT} environ_tmp >> $@; \
else \
echo '#undef HAVE_ENVIRON /* no */' >> $@; \
fi
${Q} echo '' >> $@
${Q} echo '' >> $@
${Q} echo '#endif /* !CALC_HAVE_ENVIRON_H */' >> $@
${Q} ${RM} -f have_environ${EXT} have_environ.o environ_tmp
${H} echo '$@ formed'
-@if [ -z "${Q}" ]; then \
echo ''; \
echo '=-=-= start of $@ =-=-='; \
${CAT} $@; \
echo '=-=-= end of $@ =-=-='; \
echo ''; \
else \
${TRUE}; \
fi
have_newstr.h: have_newstr.c banned.h have_ban_pragma.h ${MAKE_FILE} ${LOC_MKF} have_newstr.h: have_newstr.c banned.h have_ban_pragma.h ${MAKE_FILE} ${LOC_MKF}
${Q} ${RM} -f newstr_tmp $@ ${Q} ${RM} -f newstr_tmp $@
${H} echo 'forming $@' ${H} echo 'forming $@'
@@ -4425,6 +4479,7 @@ env:
@echo 'GREP=${GREP}'; echo '' @echo 'GREP=${GREP}'; echo ''
@echo 'H=${H}'; echo '' @echo 'H=${H}'; echo ''
@echo 'HAVE_CONST=${HAVE_CONST}'; echo '' @echo 'HAVE_CONST=${HAVE_CONST}'; echo ''
@echo 'HAVE_ENVIRON=${HAVE_ENVIRON}'; echo ''
@echo 'HAVE_FPOS=${HAVE_FPOS}'; echo '' @echo 'HAVE_FPOS=${HAVE_FPOS}'; echo ''
@echo 'HAVE_FPOS_POS=${HAVE_FPOS_POS}'; echo '' @echo 'HAVE_FPOS_POS=${HAVE_FPOS_POS}'; echo ''
@echo 'HAVE_GETPGID=${HAVE_GETPGID}'; echo '' @echo 'HAVE_GETPGID=${HAVE_GETPGID}'; echo ''
@@ -5817,6 +5872,9 @@ have_ban_pragma.o: have_ban_pragma.h
have_const.o: banned.h have_const.o: banned.h
have_const.o: have_ban_pragma.h have_const.o: have_ban_pragma.h
have_const.o: have_const.c have_const.o: have_const.c
have_environ.o: banned.h
have_environ.o: have_ban_pragma.h
have_environ.o: have_environ.c
have_fpos.o: banned.h have_fpos.o: banned.h
have_fpos.o: have_ban_pragma.h have_fpos.o: have_ban_pragma.h
have_fpos.o: have_fpos.c have_fpos.o: have_fpos.c
@@ -6456,6 +6514,7 @@ seed.o: decl.h
seed.o: endian_calc.h seed.o: endian_calc.h
seed.o: have_ban_pragma.h seed.o: have_ban_pragma.h
seed.o: have_const.h seed.o: have_const.h
seed.o: have_environ.h
seed.o: have_getpgid.h seed.o: have_getpgid.h
seed.o: have_getprid.h seed.o: have_getprid.h
seed.o: have_getsid.h seed.o: have_getsid.h

View File

@@ -34,10 +34,9 @@
* This prog outputs several defines: * This prog outputs several defines:
* *
* HAVE_GETTIME * HAVE_GETTIME
* defined ==> use clock_gettime() for either CLOCK_SGI_CYCLE * defined ==> use clock_gettime() from CLOCK_REALTIME
* and/or CLOCK_REALTIME * undefined ==> clock_gettime() is not available from
* undefined ==> clock_gettime() is not available for both * CLOCK_REALTIME
* CLOCK_SGI_CYCLE and CLOCK_REALTIME
*/ */
#include <stdio.h> #include <stdio.h>
@@ -56,13 +55,7 @@ main(void)
#else /* HAVE_NO_GETTIME */ #else /* HAVE_NO_GETTIME */
# if defined(CLOCK_SGI_CYCLE) # if defined(CLOCK_REALTIME)
struct timespec sgi_cycle; /* SGI hardware clock */
(void) clock_gettime(CLOCK_SGI_CYCLE, &sgi_cycle);
printf("#define HAVE_GETTIME /* yes - w/CLOCK_SGI_CYCLE */\n");
# elif defined(CLOCK_REALTIME)
struct timespec realtime; /* POSIX realtime clock */ struct timespec realtime; /* POSIX realtime clock */
(void) clock_gettime(CLOCK_REALTIME, &realtime); (void) clock_gettime(CLOCK_REALTIME, &realtime);
@@ -70,7 +63,7 @@ main(void)
# else # else
printf("#undef HAVE_GETTIME /* no - no SGI_CYCLE and no REALTIME */\n"); printf("#undef HAVE_GETTIME /* no - no CLOCK_REALTIME */\n");
# endif /* CLOCK_REALTIME */ # endif /* CLOCK_REALTIME */

View File

@@ -25,8 +25,8 @@ DESCRIPTION
sequence each time they are run. sequence each time they are run.
The return value of this builtin function should NOT be considered The return value of this builtin function should NOT be considered
a random or pseudo-random value. The return value should be used a random or pseudo-random value. The return value could be used
as an argument to a seed function such as srand() or srandom(). as an argument to seed functions such as srand() or srandom().
EXAMPLE EXAMPLE
; print srand(seed()) ; print srand(seed())
@@ -44,7 +44,7 @@ LINK LIBRARY
SEE ALSO SEE ALSO
seed, srand, randbit, isrand, rand, random, srandom, israndom seed, srand, randbit, isrand, rand, random, srandom, israndom
## Copyright (C) 1999,2018 Landon Curt Noll ## Copyright (C) 1999,2018,2021 Landon Curt Noll
## ##
## Calc is open software; you can redistribute it and/or modify it under ## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License ## the terms of the version 2.1 of the GNU Lesser General Public License

152
seed.c
View File

@@ -1,5 +1,5 @@
/* /*
* seed - produce a pseudo-random seeds * seed - produce pseudo-random seeds
* *
* Copyright (C) 1999-2007,2021 Landon Curt Noll * Copyright (C) 1999-2007,2021 Landon Curt Noll
* *
@@ -90,6 +90,7 @@
#include "have_urandom.h" #include "have_urandom.h"
#include "have_rusage.h" #include "have_rusage.h"
#include "have_uid_t.h" #include "have_uid_t.h"
#include "have_environ.h"
#if defined(HAVE_USTAT) #if defined(HAVE_USTAT)
# include <ustat.h> # include <ustat.h>
#endif #endif
@@ -108,13 +109,25 @@
*/ */
#if defined(HAVE_B64) #if defined(HAVE_B64)
typedef USB64 hash64; typedef USB64 hash64;
static hash64 prev_hash64 = 0; /* previous pseudo_seed() return or 0 */
#else #else
struct s_hash64 { struct s_hash64 {
USB32 w32[2]; USB32 w32[2];
}; };
typedef struct s_hash64 hash64; typedef struct s_hash64 hash64;
static hash64 prev_hash64 = { 0, 0 }; /* previous pseudo_seed() return or 0 */
#endif #endif
#if defined(HAVE_ENVIRON)
extern char **environ; /* user environment */
#endif /* HAVE_ENVIRON */
/*
* call counter - number of times pseudo_seed() as been called
*/
static FULL call_count = 0;
/* /*
* 64-bit initial basis - Based on the 64-bit FNV basis value * 64-bit initial basis - Based on the 64-bit FNV basis value
@@ -134,16 +147,16 @@ typedef struct s_hash64 hash64;
* hashed. * hashed.
* *
* Yes, even with this non-zero virgin value there is a set of data * Yes, even with this non-zero virgin value there is a set of data
* that will result in a zero hash value. Worse, appending any * that will result in a zero hash value. Worse, appending some
* about of zero bytes will continue to produce a zero hash value. * mount of zero value bytes will continue to produce a zero hash value.
* But that would happen with any initial value so long as the * But that would happen with any initial value so long as the hash
* hash of the initial was the `inverse' of the virgin prefix string. * was the hash `inverse' of the virgin prefix string.
* *
* But then again for any hash function, there exists sets of data * But then again for any hash function, there exists sets of data
* which that the hash of every member is the same value. That is * which that the hash of every member is the same value. That is
* life with many to few mapping functions. All we do here is to * life with mapping functions. All we do here is to prevent sets
* prevent sets whose members consist of 0 or more bytes of 0's from * whose members consist of 0 or more bytes of 0's from being such
* being such an awkward set. * an awkward set.
* *
* And yes, someone can figure out what the magic 'inverse' of the * And yes, someone can figure out what the magic 'inverse' of the
* 32 ASCII character are ... but this hash function is NOT intended * 32 ASCII character are ... but this hash function is NOT intended
@@ -161,27 +174,37 @@ typedef struct s_hash64 hash64;
/* /*
* private_hash64_buf - perform a Fowler/Noll/Vo-1 64 bit hash * initial_private_hash64 - initial basis of Fowler/Noll/Vo-1 64 bit hash
*
* input:
* buf - start of buffer to hash
* len - length of buffer in octets
* hval - the hash value to modify
*
* returns:
* 64 bit hash as a static hash64 structure
*/ */
S_FUNC hash64 S_FUNC hash64
private_hash64_buf(char *buf, unsigned len) initial_private_hash64(void)
{ {
hash64 hval; /* current hash value */ hash64 hval; /* current hash value */
#if !defined(HAVE_B64) #if defined(HAVE_B64)
hval = PRIVATE_64_BASIS;
#else /* HAVE_B64 */
USB32 val[4]; /* hash value in base 2^16 */ USB32 val[4]; /* hash value in base 2^16 */
USB32 tmp[4]; /* tmp 64 bit value */
#endif /* HAVE_B64 */
char *buf_end = buf+len; /* beyond end of hash area */
/* /* hash each octet of the buffer */
val[0] = PRIVATE_64_BASIS_0;
val[1] = PRIVATE_64_BASIS_1;
val[2] = PRIVATE_64_BASIS_2;
val[3] = PRIVATE_64_BASIS_3;
/* convert to hash64 */
/* hval.w32[1] = 0xffff&(val[3]<<16)+val[2]; */
hval.w32[1] = (val[3]<<16) + val[2];
hval.w32[0] = (val[1]<<16) + val[0];
#endif /* HAVE_B64 */
/* return our initial hash value */
return hval;
}
/*
* private_hash64_buf - perform a Fowler/Noll/Vo-1 64 bit hash
*
* FNV-1 - Fowler/Noll/Vo-1 64 bit hash * FNV-1 - Fowler/Noll/Vo-1 64 bit hash
* *
* The basis of this hash algorithm was taken from an idea sent * The basis of this hash algorithm was taken from an idea sent
@@ -210,10 +233,28 @@ private_hash64_buf(char *buf, unsigned len)
* FNV-1a hash function. The use of FNV-1 is kept * FNV-1a hash function. The use of FNV-1 is kept
* for backwards compatibility purposes and because * for backwards compatibility purposes and because
* the use of FNV-1 in this special purpose, suffices. * the use of FNV-1 in this special purpose, suffices.
*
* input:
* buf - start of buffer to hash
* len - length of buffer in octets
* hval - the hash value to modify
*
* returns:
* 64 bit hash as a static hash64 structure
*/ */
S_FUNC hash64
private_hash64_buf(hash64 hval, char *buf, unsigned len)
{
#if !defined(HAVE_B64)
USB32 val[4]; /* hash value in base 2^16 */
USB32 tmp[4]; /* tmp 64 bit value */
#endif /* HAVE_B64 */
char *buf_end = buf+len; /* beyond end of hash area */
#if defined(HAVE_B64) #if defined(HAVE_B64)
/* hash each octet of the buffer */ /* hash each octet of the buffer */
for (hval = PRIVATE_64_BASIS; buf < buf_end; ++buf) { for (; buf < buf_end; ++buf) {
/* multiply by 1099511628211ULL mod 2^64 using 64 bit longs */ /* multiply by 1099511628211ULL mod 2^64 using 64 bit longs */
hval *= (hash64)1099511628211ULL; hval *= (hash64)1099511628211ULL;
@@ -224,11 +265,12 @@ private_hash64_buf(char *buf, unsigned len)
#else /* HAVE_B64 */ #else /* HAVE_B64 */
/* hash each octet of the buffer */ /* load val array from hval argument */
val[0] = PRIVATE_64_BASIS_0; val[0] = hval.w32[0] & 0xffff;
val[1] = PRIVATE_64_BASIS_1; val[1] = (hval.w32[0]>>16) & 0xffff;
val[2] = PRIVATE_64_BASIS_2; val[2] = hval.w32[1] & 0xffff;
val[3] = PRIVATE_64_BASIS_3; val[3] = (hval.w32[1]>>16) & 0xffff;
for (; buf < buf_end; ++buf) { for (; buf < buf_end; ++buf) {
/* /*
@@ -241,7 +283,7 @@ private_hash64_buf(char *buf, unsigned len)
/* multiply by the lowest order digit base 2^16 */ /* multiply by the lowest order digit base 2^16 */
tmp[0] = val[0] * 0x1b3; tmp[0] = val[0] * 0x1b3;
tmp[1] = val[1] * 0x1b3; tmp[1] = val[1] * 0x1b3;
tmp[2] = val[2] * 0x1b3; tmp[1] = val[2] * 0x1b3;
tmp[3] = val[3] * 0x1b3; tmp[3] = val[3] * 0x1b3;
/* multiply by the other non-zero digit */ /* multiply by the other non-zero digit */
tmp[2] += val[0] << 8; /* tmp[2] += val[0] * 0x100 */ tmp[2] += val[0] << 8; /* tmp[2] += val[0] * 0x100 */
@@ -299,9 +341,6 @@ pseudo_seed(void)
{ {
struct { /* data used for quasi-random seed */ struct { /* data used for quasi-random seed */
#if defined(HAVE_GETTIME) #if defined(HAVE_GETTIME)
# if defined(CLOCK_SGI_CYCLE)
struct timespec sgi_cycle; /* SGI hardware clock */
# endif
# if defined(CLOCK_REALTIME) # if defined(CLOCK_REALTIME)
struct timespec realtime; /* POSIX realtime clock */ struct timespec realtime; /* POSIX realtime clock */
# endif # endif
@@ -359,25 +398,36 @@ pseudo_seed(void)
#endif #endif
time_t time; /* local time */ time_t time; /* local time */
size_t size; /* size of this data structure */ size_t size; /* size of this data structure */
hash64 prev_hash64_copy; /* copy if the previous hash value */
FULL call_count_copy; /* count pf this funcation was called */
jmp_buf env; /* setjmp() context */ jmp_buf env; /* setjmp() context */
#if defined(HAVE_ENVIRON)
char **environ_copy; /* copy of extern char **environ */
#endif /* HAVE_ENVIRON */
char *sdata_p; /* address of this structure */ char *sdata_p; /* address of this structure */
} sdata; } sdata;
hash64 hash_val; /* fnv64 hash of sdata */ hash64 hash_val; /* fnv64 hash of sdata */
ZVALUE hash; /* hash_val as a ZVALUE */ ZVALUE hash; /* hash_val as a ZVALUE */
NUMBER *ret; /* return seed as a NUMBER */ NUMBER *ret; /* return seed as a NUMBER */
#if defined(HAVE_ENVIRON)
int i;
size_t envlen; /* length of an environment variable */
#endif
/*
* initialize the Fowler/Noll/Vo-1 64 bit hash
*/
hash_val = initial_private_hash64();
/* /*
* pick up process/system information * pick up process/system information
* *
* NOTE: * NOTE:
* We do care (that much) if these calls fail. We do not * We do NOT care (that much) if these calls fail. We do not
* need to process any data in the 'sdata' structure. * need to process any data in the 'sdata' structure.
*/ */
memset(&sdata, 0, sizeof(sdata)); memset(&sdata, 0, sizeof(sdata));
#if defined(HAVE_GETTIME) #if defined(HAVE_GETTIME)
# if defined(CLOCK_SGI_CYCLE)
(void) clock_gettime(CLOCK_SGI_CYCLE, &sdata.sgi_cycle);
# endif
# if defined(CLOCK_REALTIME) # if defined(CLOCK_REALTIME)
(void) clock_gettime(CLOCK_REALTIME, &sdata.realtime); (void) clock_gettime(CLOCK_REALTIME, &sdata.realtime);
# endif # endif
@@ -441,13 +491,34 @@ pseudo_seed(void)
#endif #endif
sdata.time = time(NULL); sdata.time = time(NULL);
sdata.size = sizeof(sdata); sdata.size = sizeof(sdata);
sdata.prev_hash64_copy = prev_hash64;
sdata.call_count_copy = ++call_count;
(void) setjmp(sdata.env); (void) setjmp(sdata.env);
#if defined(HAVE_ENVIRON)
sdata.environ_copy = environ;
#endif /* HAVE_ENVIRON */
sdata.sdata_p = (char *)&sdata; sdata.sdata_p = (char *)&sdata;
/* /*
* seed the generator with the above data * seed the generator with the above data
*/ */
hash_val = private_hash64_buf((char *)&sdata, sizeof(sdata)); hash_val = private_hash64_buf(hash_val, (char *)&sdata, sizeof(sdata));
#if defined(HAVE_ENVIRON)
/*
* seed each envinment variable
*/
for (i=0; environ[i] != NULL; ++i) {
/* obtain length of this next environment variable string */
envlen = strlen(environ[i]);
/* hash any non-zero length environment variable string */
if (envlen > 0) {
hash_val = private_hash64_buf(hash_val, environ[i], envlen);
}
}
#endif /* HAVE_ENVIRON */
/* /*
* load the hash data into the ZVALUE * load the hash data into the ZVALUE
@@ -461,6 +532,11 @@ pseudo_seed(void)
memcpy((void *)hash.v, (void *)&hash_val, hash.len*sizeof(HALF)); memcpy((void *)hash.v, (void *)&hash_val, hash.len*sizeof(HALF));
ztrim(&hash); ztrim(&hash);
/*
* save hash value for next call
*/
prev_hash64 = hash_val;
/* /*
* return a number * return a number
*/ */

View File

@@ -32,6 +32,7 @@ HAVE_SYS_TIMES_H=NO
HAVE_TIME_H=YES HAVE_TIME_H=YES
HAVE_SYS_TIME_H=NO HAVE_SYS_TIME_H=NO
HAVE_UNISTD_H=NO HAVE_UNISTD_H=NO
HAVE_ENVIRON=-DHAVE_NO_ENVIRON
BINDIR=/usr/bin/calc BINDIR=/usr/bin/calc
LIBDIR=/lib/calc LIBDIR=/lib/calc