split up constants.h some
[trinity.git] / seed.c
blob1d111cbfa28aee8a203d72a33d5f0dcd1381cf0f
1 /*
2 * Routines to get/set seeds.
3 */
4 #include <syslog.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <limits.h>
10 #include "shm.h"
11 #include "params.h" // 'user_set_seed'
12 #include "pids.h"
13 #include "log.h"
14 #include "random.h"
16 /* The actual seed lives in the shm. This variable is used
17 * to store what gets passed in from the command line -s argument */
18 unsigned int seed = 0;
20 static void syslog_seed(int seedparam)
22 outputerr("Randomness reseeded to %u\n", seedparam);
23 openlog("trinity", LOG_CONS|LOG_PERROR, LOG_USER);
24 syslog(LOG_CRIT, "Randomness reseeded to %u\n", seedparam);
25 closelog();
28 unsigned int new_seed(void)
30 int fd;
31 struct timeval t;
32 unsigned int r;
34 if ((fd = open("/dev/urandom", O_RDONLY)) < 0 ||
35 read(fd, &r, sizeof(r)) != sizeof(r)) {
36 r = rand();
37 if (!(rand_bool())) {
38 gettimeofday(&t, NULL);
39 r |= t.tv_usec;
42 if (fd >= 0)
43 close(fd);
44 return r;
48 * If we passed in a seed with -s, use that. Otherwise make one up from time of day.
50 unsigned int init_seed(unsigned int seedparam)
52 if (user_set_seed == TRUE)
53 output(0, "Using user passed random seed: %u\n", seedparam);
54 else {
55 seedparam = new_seed();
57 output(0, "Initial random seed: %u\n", seedparam);
60 if (do_syslog == TRUE)
61 syslog_seed(seedparam);
63 return seedparam;
66 /* Mix in the pidslot so that all children get different randomness.
67 * we can't use the actual pid or anything else 'random' because otherwise reproducing
68 * seeds with -s would be much harder to replicate.
70 void set_seed(unsigned int pidslot)
72 srand(shm->seed + (pidslot + 1));
73 shm->seeds[pidslot] = shm->seed;
77 * Set a new seed in the parent.
78 * Called when a new child starts, so we don't repeat runs across different pids.
79 * We only reseed in the main pid, all the children are expected to periodically
80 * check if the seed changed, and reseed accordingly.
82 * Caveat: Not used if we passed in our own seed with -s
84 void reseed(void)
86 if (getpid() != shm->mainpid) {
87 outputerr("Reseeding should only happen from parent!\n");
88 exit(EXIT_FAILURE);
91 /* don't change the seed if we passed -s */
92 if (user_set_seed == TRUE)
93 return;
95 /* We are reseeding. */
96 shm->seed = new_seed();
98 output(0, "Random reseed: %u\n", shm->seed);
100 if (do_syslog == TRUE)
101 syslog_seed(shm->seed);