Skip to content

Commit

Permalink
breaking: let posixRead() return less than buffer size, introduce pos…
Browse files Browse the repository at this point in the history
…ixReadFull()

posixRead should be as thin an abstraction on top of read() as possible.

posixReadFull() really should be in io somewhere.
  • Loading branch information
shawnl committed Aug 28, 2018
1 parent 4003cd4 commit 9691422
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
2 changes: 1 addition & 1 deletion std/os/child_process.zig
Expand Up @@ -757,6 +757,6 @@ fn writeIntFd(fd: i32, value: ErrInt) !void {

fn readIntFd(fd: i32) !ErrInt {
var bytes: [@sizeOf(ErrInt)]u8 = undefined;
os.posixRead(fd, bytes[0..]) catch return error.SystemResources;
os.posixReadFull(fd, bytes[0..]) catch return error.SystemResources;
return mem.readInt(bytes[0..], ErrInt, builtin.endian);
}
33 changes: 21 additions & 12 deletions std/os/index.zig
Expand Up @@ -31,7 +31,7 @@ pub const posix = switch (builtin.os) {
Os.zen => zen,
else => @compileError("Unsupported OS"),
};
pub const net = @import("net.zig");
pub const net = std.net;

pub const ChildProcess = @import("child_process.zig").ChildProcess;
pub const path = @import("path.zig");
Expand Down Expand Up @@ -114,7 +114,7 @@ pub fn getRandomBytes(buf: []u8) !void {
const fd = try posixOpenC(c"/dev/urandom", posix.O_RDONLY | posix.O_CLOEXEC, 0);
defer close(fd);

try posixRead(fd, buf);
try posixReadFull(fd, buf);
return;
},
else => return unexpectedErrorPosix(err),
Expand All @@ -126,7 +126,7 @@ pub fn getRandomBytes(buf: []u8) !void {
const fd = try posixOpenC(c"/dev/urandom", posix.O_RDONLY | posix.O_CLOEXEC, 0);
defer close(fd);

try posixRead(fd, buf);
try posixReadFull(fd, buf);
},
Os.windows => {
// Call RtlGenRandom() instead of CryptGetRandom() on Windows
Expand Down Expand Up @@ -229,15 +229,10 @@ pub fn close(handle: FileHandle) void {
}

/// Calls POSIX read, and keeps trying if it gets interrupted.
pub fn posixRead(fd: i32, buf: []u8) !void {
// Linux can return EINVAL when read amount is > 0x7ffff000
// See https://github.com/ziglang/zig/pull/743#issuecomment-363158274
const max_buf_len = 0x7ffff000;

var index: usize = 0;
while (index < buf.len) {
const want_to_read = math.min(buf.len - index, usize(max_buf_len));
const rc = posix.read(fd, buf.ptr + index, want_to_read);
pub fn posixRead(fd: i32, buf: []u8) !usize {
// Just for EINTR
while (true) {
const rc = posix.read(fd, buf.ptr, buf.len);
const err = posix.getErrno(rc);
if (err > 0) {
return switch (err) {
Expand All @@ -251,6 +246,20 @@ pub fn posixRead(fd: i32, buf: []u8) !void {
else => unexpectedErrorPosix(err),
};
}
return rc;
}
}

/// Calls POSIX read, and keeps trying if it gets interrupted.
pub fn posixReadFull(fd: i32, buf: []u8) !void {
// Linux can return EINVAL when read amount is > 0x7ffff000
// See https://github.com/ziglang/zig/pull/743#issuecomment-363158274
const max_buf_len = 0x7ffff000;

var index: usize = 0;
while (index < buf.len) {
const want_to_read = math.min(buf.len - index, usize(max_buf_len));
const rc = try posixRead(fd, buf[index..]);
index += rc;
}
}
Expand Down

0 comments on commit 9691422

Please sign in to comment.