configure.in | 2 - src/fccache.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 11 deletions(-) New commits: commit a13d518fdd079aeb0bd07a0457393cca8def7f90 Author: Akira TAGOH <akira at tagoh.org> Date: Tue Feb 28 12:52:25 2012 +0900 Bug 41694 - FcCache functions have random-number-generator side effects Use the own random number generator state if possible. diff --git a/configure.in b/configure.in index 9f671ab..06851a5 100644 --- a/configure.in +++ b/configure.in @@ -119,7 +119,7 @@ AC_TYPE_PID_T # Checks for library functions. AC_FUNC_VPRINTF AC_FUNC_MMAP -AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48]) +AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r]) # # Checks for iconv diff --git a/src/fccache.c b/src/fccache.c index c38a705..d8102d7 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -20,14 +20,18 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ - +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "fcint.h" #include "fcarch.h" #include <stdio.h> +#include <stdlib.h> #include <fcntl.h> #include <dirent.h> #include <string.h> #include <sys/types.h> +#include <time.h> #include <assert.h> #if defined(HAVE_MMAP) || defined(__CYGWIN__) # include <unistd.h> @@ -307,17 +311,62 @@ struct _FcCacheSkip { static FcCacheSkip *fcCacheChains[FC_CACHE_MAX_LEVEL]; static int fcCacheMaxLevel; -#if HAVE_RANDOM -# define FcRandom() random() + +static int32_t +FcRandom(void) +{ + int32_t result; + +#if HAVE_RANDOM_R + static struct random_data fcrandbuf; + static char statebuf[256]; + static FcBool initialized = FcFalse; + + if (initialized != FcTrue) + { + initstate_r(time(NULL), statebuf, 256, &fcrandbuf); + initialized = FcTrue; + } + + random_r(&fcrandbuf, &result); +#elif HAVE_RANDOM + static char statebuf[256]; + char *state; + static FcBool initialized = FcFalse; + + if (initialized != FcTrue) + { + state = initstate(time(NULL), statebuf, 256); + initialized = FcTrue; + } + else + state = setstate(statebuf); + + result = random(); + + setstate(state); +#elif HAVE_LRAND48 + result = lrand48(); +#elif HAVE_RAND_R + static unsigned int seed = time(NULL); + + result = rand_r(&seed); +#elif HAVE_RAND + static FcBool initialized = FcFalse; + + if (initialized != FcTrue) + { + srand(time(NULL)); + initialized = FcTrue; + } + result = rand(); #else -# if HAVE_LRAND48 -# define FcRandom() lrand48() -# else -# if HAVE_RAND -# define FcRandom() rand() -# endif -# endif +# error no random number generator function available. #endif + + return result; +} + /* * Generate a random level number, distributed * so that each level is 1/4 as likely as the one before