From 44cff01e5bbe04ff991ede843e96f0c2d83d20c6 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 19 Sep 2024 18:03:17 +0200 Subject: Split into multiple C files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- rnd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 rnd.c (limited to 'rnd.c') diff --git a/rnd.c b/rnd.c new file mode 100644 index 0000000..7e24bf2 --- /dev/null +++ b/rnd.c @@ -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; +} -- cgit v1.2.3-70-g09d2