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
This commit is contained in:
Love Hörnquist Åstrand
2009-03-22 17:20:18 +00:00
parent 59e499f32f
commit 164c99a4b4

View File

@@ -40,11 +40,15 @@ RCSID("$Id$");
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <rand.h> #include <rand.h>
#include <heim_threads.h>
#include <roken.h> #include <roken.h>
#include "randi.h" #include "randi.h"
static int random_fd = -1;
static HEIMDAL_MUTEX random_mutex = HEIMDAL_MUTEX_INITIALIZER;
/* /*
* Unix /dev/random * Unix /dev/random
*/ */
@@ -88,31 +92,47 @@ unix_seed(const void *indata, int size)
} }
static int static int
unix_bytes(unsigned char *outdata, int size) unix_bytes(unsigned char *outdata, int size)
{ {
ssize_t count; ssize_t count;
int fd; int once = 0;
if (size <= 0) if (size <= 0)
return 0; return 0;
fd = get_device_fd(O_RDONLY); HEIMDAL_MUTEX_lock(&random_mutex);
if (fd < 0) if (random_fd == -1) {
return 0; retry:
random_fd = get_device_fd(O_RDONLY);
if (random_fd < 0) {
HEIMDAL_MUTEX_unlock(&random_mutex);
return 0;
}
}
while (size > 0) { while (size > 0) {
count = read (fd, outdata, size); HEIMDAL_MUTEX_unlock(&random_mutex);
if (count < 0 && errno == EINTR) count = read (random_fd, outdata, size);
continue; HEIMDAL_MUTEX_lock(&random_mutex);
else if (count <= 0) { if (random_fd < 0) {
close(fd); 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; return 0;
} }
outdata += count; outdata += count;
size -= count; size -= count;
} }
close(fd); HEIMDAL_MUTEX_unlock(&random_mutex);
return 1; return 1;
} }