| ... | ... | @@ -103,33 +103,41 @@ pub fn getrandom(buf: []u8) GetRandomError!void { |
| 103 | 103 | if (windows.is_the_target) { |
| 104 | 104 | return windows.RtlGenRandom(buf); |
| 105 | 105 | } |
| 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 | } |
| 110 | 123 | } 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; |
| 112 | 128 | }; |
| 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)); |
| 126 | 129 | |
| 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..]; |
| 133 | 141 | } |
| 134 | 142 | } |
| 135 | 143 | } |