diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-10-29 17:06:32 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-10-29 17:06:32 +0100 |
commit | 539618a0ddc2dc7f0fbe28de2ae0e07b34c81e60 (patch) | |
tree | 23a4a87b839413ee39636eb116b5316571c88878 /src/shared/util.c | |
parent | d0159fdc7a1009027f019f763106aa13256cf030 (diff) |
util: make use of the new getrandom() syscall if it is available when needing entropy
Doesn't require an fd, and could be a bit faster, so let's make use of
it, if it is available.
Diffstat (limited to 'src/shared/util.c')
-rw-r--r-- | src/shared/util.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index 4143f6d643..ceafba86af 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2466,14 +2466,37 @@ char* dirname_malloc(const char *path) { } int dev_urandom(void *p, size_t n) { - _cleanup_close_ int fd; + static int have_syscall = -1; + int r, fd; ssize_t k; + /* Use the syscall unless we know we don't have it, or when + * the requested size is too large for it. */ + if (have_syscall != 0 || (size_t) (int) n != n) { + r = getrandom(p, n, 0); + if (r == (int) n) { + have_syscall = true; + return 0; + } + + if (r < 0) { + if (errno == ENOSYS) + /* we lack the syscall, continue with reading from /dev/urandom */ + have_syscall = false; + else + return -errno; + } else + /* too short read? */ + return -EIO; + } + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) return errno == ENOENT ? -ENOSYS : -errno; k = loop_read(fd, p, n, true); + safe_close(fd); + if (k < 0) return (int) k; if ((size_t) k != n) |