From 164c99a4b414b614e5185a96ef8287331e9134eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Sun, 22 Mar 2009 17:20:18 +0000 Subject: [PATCH] Do locking around file descriptor, this allows caching of the file descriptor in the module. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@24901 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/hcrypto/rand-unix.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/hcrypto/rand-unix.c b/lib/hcrypto/rand-unix.c index 0c2185776..07d81eb62 100644 --- a/lib/hcrypto/rand-unix.c +++ b/lib/hcrypto/rand-unix.c @@ -40,11 +40,15 @@ RCSID("$Id$"); #include #include #include +#include #include #include "randi.h" +static int random_fd = -1; +static HEIMDAL_MUTEX random_mutex = HEIMDAL_MUTEX_INITIALIZER; + /* * Unix /dev/random */ @@ -88,31 +92,47 @@ unix_seed(const void *indata, int size) } + static int unix_bytes(unsigned char *outdata, int size) { ssize_t count; - int fd; + int once = 0; if (size <= 0) return 0; - fd = get_device_fd(O_RDONLY); - if (fd < 0) - return 0; + HEIMDAL_MUTEX_lock(&random_mutex); + if (random_fd == -1) { + retry: + random_fd = get_device_fd(O_RDONLY); + if (random_fd < 0) { + HEIMDAL_MUTEX_unlock(&random_mutex); + return 0; + } + } while (size > 0) { - count = read (fd, outdata, size); - if (count < 0 && errno == EINTR) - continue; - else if (count <= 0) { - close(fd); + HEIMDAL_MUTEX_unlock(&random_mutex); + count = read (random_fd, outdata, size); + HEIMDAL_MUTEX_lock(&random_mutex); + if (random_fd < 0) { + if (errno == EINTR) + continue; + else if (errno == EBADF && once++ == 0) { + close(random_fd); + random_fd = -1; + goto retry; + } + return 0; + } else if (count <= 0) { + HEIMDAL_MUTEX_unlock(&random_mutex); return 0; } outdata += count; size -= count; } - close(fd); + HEIMDAL_MUTEX_unlock(&random_mutex); return 1; }