diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-03-11 13:06:30 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-03-11 13:06:30 -0400 |
| commit | d96b6c0d9f7a4fc6e7e28dd92d18e548f00885de (patch) | |
| tree | 1c2774d9d9ffe279fa1ae330eec529dbdc9cb994 /lib/std/fs | |
| parent | ed13cffca4c42718cc7239faf7aab642ac67ef77 (diff) | |
| download | zig-d96b6c0d9f7a4fc6e7e28dd92d18e548f00885de.tar.gz zig-d96b6c0d9f7a4fc6e7e28dd92d18e548f00885de.zip | |
fix footguns in File readAll functions
Diffstat (limited to 'lib/std/fs')
| -rw-r--r-- | lib/std/fs/file.zig | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index 845e4bc75e..8362f94ca5 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -250,11 +250,16 @@ pub const File = struct { } } - pub fn readAll(self: File, buffer: []u8) ReadError!void { + /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it + /// means the file reached the end. Reaching the end of a file is not an error condition. + pub fn readAll(self: File, buffer: []u8) ReadError!usize { var index: usize = 0; - while (index < buffer.len) { - index += try self.read(buffer[index..]); + while (index != buffer.len) { + const amt = try self.read(buffer[index..]); + if (amt == 0) break; + index += amt; } + return index; } pub fn pread(self: File, buffer: []u8, offset: u64) PReadError!usize { @@ -265,11 +270,16 @@ pub const File = struct { } } - pub fn preadAll(self: File, buffer: []u8, offset: u64) PReadError!void { + /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it + /// means the file reached the end. Reaching the end of a file is not an error condition. + pub fn preadAll(self: File, buffer: []u8, offset: u64) PReadError!usize { var index: usize = 0; - while (index < buffer.len) { - index += try self.pread(buffer[index..], offset + index); + while (index != buffer.len) { + const amt = try self.pread(buffer[index..], offset + index); + if (amt == 0) break; + index += amt; } + return index; } pub fn readv(self: File, iovecs: []const os.iovec) ReadError!usize { @@ -280,19 +290,27 @@ pub const File = struct { } } + /// Returns the number of bytes read. If the number read is smaller than the total bytes + /// from all the buffers, it means the file reached the end. Reaching the end of a file + /// is not an error condition. /// The `iovecs` parameter is mutable because this function needs to mutate the fields in /// order to handle partial reads from the underlying OS layer. - pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!void { + pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize { if (iovecs.len == 0) return; var i: usize = 0; + var off: usize = 0; while (true) { var amt = try self.readv(iovecs[i..]); + var eof = amt == 0; + off += amt; while (amt >= iovecs[i].iov_len) { amt -= iovecs[i].iov_len; i += 1; - if (i >= iovecs.len) return; + if (i >= iovecs.len) return off; + eof = false; } + if (eof) return off; iovecs[i].iov_base += amt; iovecs[i].iov_len -= amt; } @@ -306,6 +324,9 @@ pub const File = struct { } } + /// Returns the number of bytes read. If the number read is smaller than the total bytes + /// from all the buffers, it means the file reached the end. Reaching the end of a file + /// is not an error condition. /// The `iovecs` parameter is mutable because this function needs to mutate the fields in /// order to handle partial reads from the underlying OS layer. pub fn preadvAll(self: File, iovecs: []const os.iovec, offset: u64) PReadError!void { @@ -315,12 +336,15 @@ pub const File = struct { var off: usize = 0; while (true) { var amt = try self.preadv(iovecs[i..], offset + off); + var eof = amt == 0; off += amt; while (amt >= iovecs[i].iov_len) { amt -= iovecs[i].iov_len; i += 1; - if (i >= iovecs.len) return; + if (i >= iovecs.len) return off; + eof = false; } + if (eof) return off; iovecs[i].iov_base += amt; iovecs[i].iov_len -= amt; } |
