diff options
author | Mattias Andrée <maandree@kth.se> | 2024-09-19 18:03:17 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2024-09-19 18:03:17 +0200 |
commit | 44cff01e5bbe04ff991ede843e96f0c2d83d20c6 (patch) | |
tree | f889f60eca251d716489e3b30994c435c00dbfa2 /rnd.c | |
parent | m fixes (diff) | |
download | deadshred-44cff01e5bbe04ff991ede843e96f0c2d83d20c6.tar.gz deadshred-44cff01e5bbe04ff991ede843e96f0c2d83d20c6.tar.bz2 deadshred-44cff01e5bbe04ff991ede843e96f0c2d83d20c6.tar.xz |
Split into multiple C files
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | rnd.c | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -0,0 +1,80 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static char reservoir[128U << 10]; +static size_t reservoir_off = sizeof(reservoir); +static int random_fd; +static const char *random_fname; + + +size_t +max_blksize(void) +{ + size_t ret = sizeof(reservoir); + while (ret & (ret - 1U)) + ret &= ret - 1U; + return ret; +} + + +void +init_random(int fd, const char *fname) +{ + struct stat st; + + random_fname = fname; + random_fd = fd; + + errno = 0; + if (isatty(random_fd) || errno == EBADF) { + use_builtin_generator: + random_fd = -1; + libsimple_srand(); + } else if (fstat(random_fd, &st)) { + if (errno == EBADF) + goto use_builtin_generator; + eprintf("fstat %s:", random_fname); + } else if (S_ISFIFO(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode)) { + eprintf("%s is of a unsupported inode type (must be TTY, character device, FIFO, or socket)", fname); + } +} + + +const char * +get_random(size_t needed) +{ + size_t off; + ssize_t r; + + if (sizeof(reservoir) - reservoir_off >= needed) + return &reservoir[reservoir_off]; + + if (random_fd < 0) { + libsimple_random_bytes(&libsimple_random_bits, NULL, reservoir, reservoir_off); + reservoir_off = 0; + return reservoir; + } + + for (off = 0; off < reservoir_off;) { + r = read(random_fd, &reservoir[off], reservoir_off - off); + if (r <= 0) { + if (!r) + eprintf("random source depleted"); + if (errno == EINTR) + continue; + eprintf("read %s:", random_fname); + } + off += (size_t)r; + } + + reservoir_off = 0; + return reservoir; +} + + +void +used_random(ssize_t amount) +{ + reservoir_off += (size_t)amount; +} |