diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index 3d5736d37b..71dd4705f8 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -6,4 +6,4 @@ pub const _errno = __error; pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; -pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int; +pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; diff --git a/std/c/linux.zig b/std/c/linux.zig index a69f3c18b2..b3b3cbdde7 100644 --- a/std/c/linux.zig +++ b/std/c/linux.zig @@ -7,7 +7,7 @@ pub const _errno = __errno_location; pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize)); -pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int; +pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int; pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int; pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int; diff --git a/std/os.zig b/std/os.zig index 58ee569f0c..0291282a77 100644 --- a/std/os.zig +++ b/std/os.zig @@ -99,55 +99,46 @@ pub const GetRandomError = OpenError; /// When linking against libc, this calls the /// appropriate OS-specific library call. Otherwise it uses the zig standard /// library implementation. -pub fn getrandom(buf: []u8) GetRandomError!void { +pub fn getrandom(buffer: []u8) GetRandomError!void { if (windows.is_the_target) { - return windows.RtlGenRandom(buf); + return windows.RtlGenRandom(buffer); } if (linux.is_the_target or freebsd.is_the_target) { - var buf_slice: []u8 = buf[0..]; - var total_read: usize = 0; - const use_c = (!linux.is_the_target) or std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok; + var buf = buffer; + const use_c = !linux.is_the_target or + std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok; - while (total_read < buf.len) { - var err: u16 = 0; + while (buf.len != 0) { + var err: u16 = undefined; - const num_read: usize = if (use_c) blk: { - const res: c_int = std.c.getrandom(buf_slice.ptr, buf_slice.len, 0); - - if (res == -1) { - err = @intCast(u16, std.c._errno().*); - break :blk 0; - } else { - break :blk @intCast(usize, res); - } + const num_read = if (use_c) blk: { + const rc = std.c.getrandom(buf.ptr, buf.len, 0); + err = std.c.getErrno(rc); + break :blk @bitCast(usize, rc); } else blk: { - const res: usize = linux.getrandom(buf_slice.ptr, buf_slice.len, 0); - - err = @intCast(u16, linux.getErrno(res)); - break :blk res; + const rc = linux.getrandom(buf.ptr, buf.len, 0); + err = linux.getErrno(rc); + break :blk rc; }; - if (err != 0) { - switch (err) { - EINVAL => unreachable, - EFAULT => unreachable, - EINTR => continue, - ENOSYS => return getRandomBytesDevURandom(buf), - else => return unexpectedErrno(err), - } - } else { - total_read += num_read; - buf_slice = buf_slice[num_read..]; + switch (err) { + 0 => buf = buf[num_read..], + EINVAL => unreachable, + EFAULT => unreachable, + EINTR => continue, + ENOSYS => return getRandomBytesDevURandom(buf), + else => return unexpectedErrno(err), } } + return; } if (wasi.is_the_target) { - switch (wasi.random_get(buf.ptr, buf.len)) { + switch (wasi.random_get(buffer.ptr, buffer.len)) { 0 => return, else => |err| return unexpectedErrno(err), } } - return getRandomBytesDevURandom(buf); + return getRandomBytesDevURandom(buffer); } fn getRandomBytesDevURandom(buf: []u8) !void {