unlock and close cachefile if we bail out of socket creation.
[trinity.git] / seed.c
bloba9e7458e48f1cd45b12b55994c9a319e760076d3
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, 0);
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 * Periodically reseed.
79 * We do this so we can log a new seed every now and again, so we can cut down on the
80 * amount of time necessary to reproduce a bug.
81 * Caveat: Not used if we passed in our own seed with -s
83 void reseed(void)
85 shm->need_reseed = FALSE;
86 shm->reseed_counter = 0;
88 if (getpid() != shm->mainpid) {
89 outputerr("Reseeding should only happen from parent!\n");
90 exit(EXIT_FAILURE);
93 /* don't change the seed if we passed -s */
94 if (user_set_seed == TRUE)
95 return;
97 /* We are reseeding. */
98 shm->seed = new_seed();
100 output(0, "Random reseed: %u\n", shm->seed);
102 if (do_syslog == TRUE)
103 syslog_seed(shm->seed);