authorgravatar for euantorano@gmail.comEuan Torano <euantorano@gmail.com> 2019-08-05 19:39:04+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-20 14:52:38-04:00
log79354243e32b0e64f4dc93bb581ff1b3061e3861
treedc4dad4824ed6ae8ae45f58bf153bef8d26658d6
parent8c32c09807ed5ae28afce3e9cf3145f350f8c4e3
signature Commit is signed but in an unrecognized format.

fix os.getrandom logic to fill the entire buffer


1 files changed, 32 insertions(+), 24 deletions(-)

std/os.zig+32-24
......@@ -103,33 +103,41 @@ pub fn getrandom(buf: []u8) GetRandomError!void {
103103 if (windows.is_the_target) {
104104 return windows.RtlGenRandom(buf);
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_slice: []u8 = buf[0..];
108 var total_read: usize = 0;
109 const use_c = (!linux.is_the_target) or std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;
110
111 while (total_read < buf.len) {
112 var err: u16 = 0;
113
114 const num_read: usize = if (use_c) blk: {
115 const res: c_int = std.c.getrandom(buf_slice.ptr, buf_slice.len, 0);
116
117 if (res == -1) {
118 err = @intCast(u16, std.c._errno().*);
119 break :blk 0;
120 } else {
121 break :blk @intCast(usize, res);
122 }
110123 } else blk: {
111 break :blk linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0));
124 const res: usize = linux.getrandom(buf_slice.ptr, buf_slice.len, 0);
125
126 err = @intCast(u16, linux.getErrno(res));
127 break :blk res;
112128 };
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));
126129
127 switch (err) {
128 0 => return,
129 EINVAL => unreachable,
130 EFAULT => unreachable,
131 EINTR => continue,
132 else => return unexpectedErrno(err),
130 if (err != 0) {
131 switch (err) {
132 EINVAL => unreachable,
133 EFAULT => unreachable,
134 EINTR => continue,
135 ENOSYS => return getRandomBytesDevURandom(buf),
136 else => return unexpectedErrno(err),
137 }
138 } else {
139 total_read += num_read;
140 buf_slice = buf_slice[num_read..];
133141 }
134142 }
135143 }