v
Зеркало из https://github.com/vlang/v
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module rand
5
6#include <sys/syscall.h>
7
8const read_batch_size = 256
9
10// read returns an array of `bytes_needed` random bytes read from the OS.
11pub fn read(bytes_needed int) ![]u8 {
12mut buffer := unsafe { vcalloc_noscan(bytes_needed) }
13mut bytes_read := 0
14mut remaining_bytes := bytes_needed
15// getrandom syscall wont block if requesting <= 256 bytes
16for bytes_read < bytes_needed {
17batch_size := if remaining_bytes > read_batch_size {
18read_batch_size
19} else {
20remaining_bytes
21}
22rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) }
23if rbytes == -1 {
24unsafe { free(buffer) }
25return &ReadError{}
26}
27bytes_read += rbytes
28}
29return unsafe { buffer.vbytes(bytes_needed) }
30}
31
32fn getrandom(bytes_needed int, buffer voidptr) int {
33if bytes_needed > read_batch_size {
34panic('getrandom() dont request more than ${read_batch_size} bytes at once.')
35}
36return unsafe { C.syscall(C.SYS_getrandom, buffer, bytes_needed, 0) }
37}
38