~ chicken-core (chicken-5) fda751c76009c47d4a633dfb35ea5a8277ee0c04
commit fda751c76009c47d4a633dfb35ea5a8277ee0c04 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Sun Nov 5 01:00:47 2017 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Sun Nov 5 01:00:47 2017 +0100 fix wrong type in chicken.h, add urandom fallback when syscall fails Thanks to florz for this suggestion diff --git a/chicken.h b/chicken.h index b0a7de30..6cab3f33 100644 --- a/chicken.h +++ b/chicken.h @@ -735,7 +735,7 @@ void *alloca (); # define C_MAX_PATH 1024 #endif -#define C_RANDOM_STATE_SIZE (16 * sizeof(C_u32)) +#define C_RANDOM_STATE_SIZE (16 * sizeof(C_uword)) /* Types: */ diff --git a/runtime.c b/runtime.c index fad58c06..93733761 100644 --- a/runtime.c +++ b/runtime.c @@ -12544,6 +12544,35 @@ BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); #endif +#if !defined(_WIN32) +static C_word random_urandom(C_word buf, int count) +{ + static int fd = -1; + int off = 0, r; + + if(fd == -1) { + fd = open("/dev/urandom", O_RDONLY); + + if(fd == -1) return C_SCHEME_FALSE; + } + + while(count > 0) { + r = read(fd, C_data_pointer(buf) + off, count); + + if(r == -1) { + if(errno != EINTR && errno != EAGAIN) return C_SCHEME_FALSE; + else r = 0; + } + + count -= r; + off += r; + } + + return C_SCHEME_TRUE; +} +#endif + + C_word C_random_bytes(C_word buf, C_word size) { int count = C_unfix(size); @@ -12558,7 +12587,8 @@ C_word C_random_bytes(C_word buf, C_word size) r = syscall(SYS_getrandom, C_data_pointer(buf) + off, count, 1); if(r == -1) { - if(errno != EINTR) return C_SCHEME_FALSE; + if(errno == ENOSYS) return random_urandom(buf, count); + else if(errno != EINTR) return C_SCHEME_FALSE; else r = 0; } @@ -12569,28 +12599,9 @@ C_word C_random_bytes(C_word buf, C_word size) if(!RtlGenRandom((PVOID)C_data_pointer(buf), (LONG)count)) return C_SCHEME_FALSE; #else - static int fd = -1; - - if(fd == -1) { - fd = open("/dev/urandom", O_RDONLY); - - if(fd == -1) { - return C_SCHEME_FALSE; - } - } - - while(count > 0) { - r = read(fd, C_data_pointer(buf) + off, count); - - if(r == -1) { - if(errno != EINTR && errno != EAGAIN) return C_SCHEME_FALSE; - else r = 0; - } - - count -= r; - off += r; - } + return random_urandom(buf, count); #endif + return C_SCHEME_TRUE; }Trap