diff options
Diffstat (limited to 'v_windows/v/vlib/crypto/rand/rand_linux.c.v')
-rw-r--r-- | v_windows/v/vlib/crypto/rand/rand_linux.c.v | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/v_windows/v/vlib/crypto/rand/rand_linux.c.v b/v_windows/v/vlib/crypto/rand/rand_linux.c.v new file mode 100644 index 0000000..52ff3da --- /dev/null +++ b/v_windows/v/vlib/crypto/rand/rand_linux.c.v @@ -0,0 +1,39 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module rand + +#include <sys/syscall.h> + +const ( + read_batch_size = 256 +) + +// read returns an array of `bytes_needed` random bytes read from the OS. +pub fn read(bytes_needed int) ?[]byte { + mut buffer := unsafe { malloc_noscan(bytes_needed) } + mut bytes_read := 0 + mut remaining_bytes := bytes_needed + // getrandom syscall wont block if requesting <= 256 bytes + for bytes_read < bytes_needed { + batch_size := if remaining_bytes > rand.read_batch_size { + rand.read_batch_size + } else { + remaining_bytes + } + rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) } + if rbytes == -1 { + unsafe { free(buffer) } + return IError(&ReadError{}) + } + bytes_read += rbytes + } + return unsafe { buffer.vbytes(bytes_needed) } +} + +fn getrandom(bytes_needed int, buffer voidptr) int { + if bytes_needed > rand.read_batch_size { + panic('getrandom() dont request more than $rand.read_batch_size bytes at once.') + } + return unsafe { C.syscall(C.SYS_getrandom, buffer, bytes_needed, 0) } +} |