Commit 9bf283c085

Andrew Kelley <andrew@ziglang.org>
2019-08-20 21:25:30
fixups
* getrandom libc prototypes had the wrong return type * `total_read` local variable was unnecessary since the sub-slice buffer has a length * I was able to get rid of all the integer casts * the err == 0 check can be a switch case * add missing `return` statement
1 parent 7935424
Changed files (3)
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;
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;
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;
-
-        while (total_read < buf.len) {
-            var err: u16 = 0;
-
-            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);
-                }
-            } else blk: {
-                const res: usize = linux.getrandom(buf_slice.ptr, buf_slice.len, 0);
+        var buf = buffer;
+        const use_c = !linux.is_the_target or
+            std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;
+
+        while (buf.len != 0) {
+            var err: u16 = undefined;
 
-                err = @intCast(u16, linux.getErrno(res));
-                break :blk 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 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 {