authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-20 15:54:09-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-20 15:54:09-04:00
log3b5a8858c29582daf37856534abe150b568a7bb7
tree44eeb261c01821f2a6d442ae01db83c7fbca671f
parentc175e53564e206f90dd8bd224b2db2fb7eca7c27
parent9bf283c0851b39d6c54d1f5dfb5c2c55cd0a1ab0
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'euantorano-fix/3012-os-getrandom-fill-buffer'

Closes #3016 Closes #3012 Thanks @euantorano!

4 files changed, 25 insertions(+), 26 deletions(-)

std/c/freebsd.zig+1-1
...@@ -6,4 +6,4 @@ pub const _errno = __error;...@@ -6,4 +6,4 @@ pub const _errno = __error;
66
7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
8pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;8pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
9pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;9pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
std/c/linux.zig+1-1
...@@ -7,7 +7,7 @@ pub const _errno = __errno_location;...@@ -7,7 +7,7 @@ pub const _errno = __errno_location;
77
8pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));8pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
99
10pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;10pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
11pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;11pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
12pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;12pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
13pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int;13pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int;
std/io.zig+1-1
...@@ -146,7 +146,7 @@ pub fn InStream(comptime ReadError: type) type {...@@ -146,7 +146,7 @@ pub fn InStream(comptime ReadError: type) type {
146146
147 /// Same as `readFull` but end of stream returns `error.EndOfStream`.147 /// Same as `readFull` but end of stream returns `error.EndOfStream`.
148 pub fn readNoEof(self: *Self, buf: []u8) !void {148 pub fn readNoEof(self: *Self, buf: []u8) !void {
149 const amt_read = try self.read(buf);149 const amt_read = try self.readFull(buf);
150 if (amt_read < buf.len) return error.EndOfStream;150 if (amt_read < buf.len) return error.EndOfStream;
151 }151 }
152152
std/os.zig+22-23
...@@ -99,47 +99,46 @@ pub const GetRandomError = OpenError;...@@ -99,47 +99,46 @@ pub const GetRandomError = OpenError;
99/// When linking against libc, this calls the99/// When linking against libc, this calls the
100/// appropriate OS-specific library call. Otherwise it uses the zig standard100/// appropriate OS-specific library call. Otherwise it uses the zig standard
101/// library implementation.101/// library implementation.
102pub fn getrandom(buf: []u8) GetRandomError!void {102pub fn getrandom(buffer: []u8) GetRandomError!void {
103 if (windows.is_the_target) {103 if (windows.is_the_target) {
104 return windows.RtlGenRandom(buf);104 return windows.RtlGenRandom(buffer);
105 }105 }
106 if (linux.is_the_target) {106 if (linux.is_the_target or freebsd.is_the_target) {
107 while (true) {107 var buf = buffer;
108 const err = if (std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok) blk: {108 const use_c = !linux.is_the_target or
109 break :blk errno(std.c.getrandom(buf.ptr, buf.len, 0));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);
110 } else blk: {118 } 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;
112 };122 };
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
127 switch (err) {124 switch (err) {
128 0 => return,125 0 => buf = buf[num_read..],
129 EINVAL => unreachable,126 EINVAL => unreachable,
130 EFAULT => unreachable,127 EFAULT => unreachable,
131 EINTR => continue,128 EINTR => continue,
129 ENOSYS => return getRandomBytesDevURandom(buf),
132 else => return unexpectedErrno(err),130 else => return unexpectedErrno(err),
133 }131 }
134 }132 }
133 return;
135 }134 }
136 if (wasi.is_the_target) {135 if (wasi.is_the_target) {
137 switch (wasi.random_get(buf.ptr, buf.len)) {136 switch (wasi.random_get(buffer.ptr, buffer.len)) {
138 0 => return,137 0 => return,
139 else => |err| return unexpectedErrno(err),138 else => |err| return unexpectedErrno(err),
140 }139 }
141 }140 }
142 return getRandomBytesDevURandom(buf);141 return getRandomBytesDevURandom(buffer);
143}142}
144143
145fn getRandomBytesDevURandom(buf: []u8) !void {144fn getRandomBytesDevURandom(buf: []u8) !void {