9 #include "randomness.h"
12 static int randomness_fd_
= -1;
14 int randomness_init(const char *filename
) {
15 if (filename
!= NULL
) {
16 randomness_fd_
= open(filename
, O_RDONLY
);
17 if (randomness_fd_
== -1) {
18 NOTIFY_ERROR("%s('%s'):%s", "open", filename
, strerror(errno
));
21 NOTIFY_DEBUG("reading randomness from '%s', fd:%d", filename
, randomness_fd_
);
23 if (randomness_fd_
!= -1) {
24 close(randomness_fd_
);
27 srand48(time(NULL
) ^ getpid());
28 NOTIFY_DEBUG("reading randomness from system PRNG");
35 Room for improvement: constrain bits of randomness consumed, based on #limit
36 Also maybe read chunks of randomness at a time
38 unsigned long randomness_upto_inclusive(unsigned long limit
) {
39 unsigned long randomness
;
44 if (randomness_fd_
!= -1) {
48 len
= read(randomness_fd_
, &randomness
, sizeof randomness
);
49 } while (len
== -1 && (errno
== EINTR
|| errno
== EAGAIN
));
50 if (len
== sizeof randomness
) {
51 randomness
%= limit
+ 1;
52 NOTIFY_DEBUG("randomness:%lu", randomness
);
55 NOTIFY_ERROR("%s(%d, %zu):%zd:%s",
56 "read", randomness_fd_
, sizeof randomness
, len
,
57 (len
< 0) ? strerror(errno
) : ( (len
== 0) ? "EOF" : "not enough read" )
61 /* fall back to pseudo-randomness if read failed */
62 randomness
= mrand48();
63 randomness
%= limit
+ 1;
65 NOTIFY_DEBUG("randomness:%lu", randomness
);