~ 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