"Fossies" - the Fresh Open Source Software Archive

Member "littleutils-1.2.5/littleutils/rand_funcs.c" (29 Oct 2021, 3170 Bytes) of package /linux/privat/littleutils-1.2.5.tar.lz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rand_funcs.c" see the Fossies "Dox" file reference documentation.

    1 /* rand_funcs.c:  General purpose random number functions.
    2 
    3    Copyright (C) 2021 by Brian Lindholm.
    4    This file is part of the littleutils utility set.
    5 
    6    The rand_funcs.c file is free software; you can redistribute it and/or
    7    modify it under the terms of the GNU General Public License as published by
    8    the Free Software Foundation; either version 3, or (at your option) any
    9    later version.
   10 
   11    The randomize utility is distributed in the hope that it will be useful, but
   12    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   14    more details.
   15 
   16    You should have received a copy of the GNU General Public License along with
   17    the littleutils.  If not, see <https://www.gnu.org/licenses/>. */
   18 
   19 
   20 #include <config.h>
   21 
   22 #include <fcntl.h>
   23 #ifdef HAVE_STDIO_H
   24 # include <stdio.h>
   25 #endif
   26 #ifdef HAVE_STDLIB_H
   27 # include <stdlib.h>
   28 #endif
   29 #ifdef HAVE_SYS_RANDOM_H
   30 # include <sys/random.h>
   31 #endif
   32 #include <time.h>
   33 #ifdef HAVE_UNISTD_H
   34 # include <unistd.h>
   35 #endif
   36 
   37 #ifdef DJGPP
   38 /* speed up stat command for DJGPP */
   39 unsigned short _djstat_flags = 63;
   40 #endif
   41 
   42 #include "rand_funcs.h"
   43 
   44 /* initialize random number generator seed */
   45 void rand_seed ()
   46 {
   47   int urandom_worked = 1;
   48   ssize_t bytes;
   49 #ifdef HAVE_CLOCK_GETTIME
   50   struct timespec junk, res;
   51 #else
   52   time_t junk;
   53 #endif
   54   unsigned short seed[3];
   55 
   56   /* pre-populate array for seed using /dev/urandom */
   57 #ifdef HAVE_GETRANDOM
   58   bytes = getrandom(seed, sizeof seed, GRND_NONBLOCK);
   59   if (bytes < 6) {
   60     urandom_worked = 0;
   61   }
   62 #else
   63   int URANDOM = open("/dev/urandom", O_RDONLY);
   64   if (URANDOM < 0) {
   65     urandom_worked = 0;
   66   }
   67   else {
   68     /* use read instead of buffered fread to avoid grabbing extra bytes */
   69     bytes = read(URANDOM, seed, sizeof seed);
   70     if (bytes < 6) {
   71       urandom_worked = 0;
   72     }
   73   }
   74   close(URANDOM);
   75 #endif
   76 
   77   /* fall back to time and PID combo if /dev/urandom failed */
   78   if (urandom_worked == 0) {
   79 #ifdef HAVE_CLOCK_GETTIME
   80     (void) clock_getres(CLOCK_MONOTONIC, &res);
   81     (void) clock_gettime(CLOCK_MONOTONIC, &junk);
   82     seed[0] = (unsigned short) ((junk.tv_nsec / res.tv_nsec) & 0xFFFF);
   83     seed[1] = (unsigned short) (getpid () & 0xFFFF);
   84     seed[2] = (unsigned short) (junk.tv_sec & 0xFFFF);
   85 #else
   86     (void) time (&junk);
   87     seed[0] = (unsigned short) (junk & 0xFFFF);
   88     seed[1] = (unsigned short) (getpid () & 0xFFFF);
   89     seed[2] = (unsigned short) ((junk >> 16) & 0xFFFF);
   90 #endif
   91   }
   92 
   93   /* initialize random number generator seed */
   94 #ifdef HAVE_LRAND48
   95   (void) seed48 (seed);
   96 #elif defined(HAVE_RANDOM)
   97   srandom (((unsigned int) seed[0] << 16) + (unsigned int) seed[1]);
   98 #else
   99   srand (((unsigned int) seed[0] << 16) + (unsigned int) seed[1]);
  100 #endif
  101 }
  102 
  103 /* generate a random integer between 0 and n-1 */
  104 size_t rand_int (size_t n)
  105 {
  106   size_t x;
  107 
  108 #if defined(HAVE_LRAND48)
  109   x = (size_t) ((double) n * drand48 ());
  110 #elif defined(HAVE_RANDOM)
  111   x = (size_t) ((double) n * ((double) random () / (double) 2147483648.0));
  112 #else
  113   x = (size_t) ((double) n * ((double) rand () / ((double) RAND_MAX + 1.0)));
  114 #endif
  115   if (x > (n - 1))
  116     x = 0;
  117   return (x);
  118 }