~ 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