summaryrefslogtreecommitdiff
path: root/random.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-07 06:26:06 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-07 06:26:06 +0000
commitbcd96d92f3239aff3152afe8ff4e72f3aa2ea287 (patch)
tree3d73b4fdfc35dd9fb159c093ca9a38ddf0120c22 /random.c
parente96955e8f63be2ae5a4999487c00c3237f922371 (diff)
random.c: try getrandom
* random.c (fill_random_bytes_syscall): try getrandom system call on Linux if supported by the kernel. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51182 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'random.c')
-rw-r--r--random.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/random.c b/random.c
index a5a63629e4..853c287040 100644
--- a/random.c
+++ b/random.c
@@ -77,6 +77,12 @@ The original copyright notice follows.
#include <sys/time.h>
#endif
+#ifdef HAVE_SYSCALL_H
+#include <syscall.h>
+#elif defined HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h>
+#endif
+
#ifdef _WIN32
# if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0400
# undef _WIN32_WINNT
@@ -84,8 +90,8 @@ The original copyright notice follows.
# undef __WINCRYPT_H__
# endif
#include <wincrypt.h>
-#include "ruby_atomic.h"
#endif
+#include "ruby_atomic.h"
typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
@@ -509,6 +515,22 @@ fill_random_bytes_syscall(void *seed, size_t size)
CryptGenRandom(prov, size, seed);
return 0;
}
+#elif defined __linux__ && defined SYS_getrandom
+static int
+fill_random_bytes_syscall(void *seed, size_t size)
+{
+ static rb_atomic_t try_syscall = 1;
+ if (try_syscall) {
+ errno = 0;
+ ret = syscall(SYS_getrandom, seed, size, 0)
+ if (errno == ENOSYS) {
+ try_syscall = 0;
+ return -1;
+ }
+ if ((size_t)ret == size) return 0;
+ }
+ return 0;
+}
#else
# define fill_random_bytes_syscall(seed, size) -1
#endif