Skip to content

Commit 3b5a885

Browse files
committed
Merge branch 'euantorano-fix/3012-os-getrandom-fill-buffer'
Closes #3016 Closes #3012 Thanks @euantorano!
2 parents c175e53 + 9bf283c commit 3b5a885

File tree

4 files changed

+25
-26
lines changed

4 files changed

+25
-26
lines changed

std/c/freebsd.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ pub const _errno = __error;
66

77
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
88
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
9-
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
9+
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;

std/c/linux.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub const _errno = __errno_location;
77

88
pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
99

10-
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
10+
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
1111
pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
1212
pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
1313
pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int;

std/io.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ pub fn InStream(comptime ReadError: type) type {
146146

147147
/// Same as `readFull` but end of stream returns `error.EndOfStream`.
148148
pub fn readNoEof(self: *Self, buf: []u8) !void {
149-
const amt_read = try self.read(buf);
149+
const amt_read = try self.readFull(buf);
150150
if (amt_read < buf.len) return error.EndOfStream;
151151
}
152152

std/os.zig

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -99,47 +99,46 @@ pub const GetRandomError = OpenError;
9999
/// When linking against libc, this calls the
100100
/// appropriate OS-specific library call. Otherwise it uses the zig standard
101101
/// library implementation.
102-
pub fn getrandom(buf: []u8) GetRandomError!void {
102+
pub fn getrandom(buffer: []u8) GetRandomError!void {
103103
if (windows.is_the_target) {
104-
return windows.RtlGenRandom(buf);
104+
return windows.RtlGenRandom(buffer);
105105
}
106-
if (linux.is_the_target) {
107-
while (true) {
108-
const err = if (std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok) blk: {
109-
break :blk errno(std.c.getrandom(buf.ptr, buf.len, 0));
106+
if (linux.is_the_target or freebsd.is_the_target) {
107+
var buf = buffer;
108+
const use_c = !linux.is_the_target or
109+
std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;
110+
111+
while (buf.len != 0) {
112+
var err: u16 = undefined;
113+
114+
const num_read = if (use_c) blk: {
115+
const rc = std.c.getrandom(buf.ptr, buf.len, 0);
116+
err = std.c.getErrno(rc);
117+
break :blk @bitCast(usize, rc);
110118
} else blk: {
111-
break :blk linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0));
119+
const rc = linux.getrandom(buf.ptr, buf.len, 0);
120+
err = linux.getErrno(rc);
121+
break :blk rc;
112122
};
113-
switch (err) {
114-
0 => return,
115-
EINVAL => unreachable,
116-
EFAULT => unreachable,
117-
EINTR => continue,
118-
ENOSYS => return getRandomBytesDevURandom(buf),
119-
else => return unexpectedErrno(err),
120-
}
121-
}
122-
}
123-
if (freebsd.is_the_target) {
124-
while (true) {
125-
const err = std.c.getErrno(std.c.getrandom(buf.ptr, buf.len, 0));
126123

127124
switch (err) {
128-
0 => return,
125+
0 => buf = buf[num_read..],
129126
EINVAL => unreachable,
130127
EFAULT => unreachable,
131128
EINTR => continue,
129+
ENOSYS => return getRandomBytesDevURandom(buf),
132130
else => return unexpectedErrno(err),
133131
}
134132
}
133+
return;
135134
}
136135
if (wasi.is_the_target) {
137-
switch (wasi.random_get(buf.ptr, buf.len)) {
136+
switch (wasi.random_get(buffer.ptr, buffer.len)) {
138137
0 => return,
139138
else => |err| return unexpectedErrno(err),
140139
}
141140
}
142-
return getRandomBytesDevURandom(buf);
141+
return getRandomBytesDevURandom(buffer);
143142
}
144143

145144
fn getRandomBytesDevURandom(buf: []u8) !void {

0 commit comments

Comments
 (0)