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 <stdlib.h>
#include <rand.h>
#include <heim_threads.h>
#include <roken.h>
#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;
}