Commit c065e12dbe
lib/std/fs/file.zig
@@ -482,7 +482,7 @@ pub const File = struct {
/// order to handle partial reads from the underlying OS layer.
/// See https://github.com/ziglang/zig/issues/7699
pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize {
- if (iovecs.len == 0) return;
+ if (iovecs.len == 0) return 0;
var i: usize = 0;
var off: usize = 0;
@@ -524,8 +524,8 @@ pub const File = struct {
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
/// order to handle partial reads from the underlying OS layer.
/// See https://github.com/ziglang/zig/issues/7699
- pub fn preadvAll(self: File, iovecs: []const os.iovec, offset: u64) PReadError!void {
- if (iovecs.len == 0) return;
+ pub fn preadvAll(self: File, iovecs: []os.iovec, offset: u64) PReadError!usize {
+ if (iovecs.len == 0) return 0;
var i: usize = 0;
var off: usize = 0;
lib/std/fs/test.zig
@@ -520,6 +520,89 @@ test "makePath, put some files in it, deleteTree" {
}
}
+test "writev, readv" {
+ var tmp = tmpDir(.{});
+ defer tmp.cleanup();
+
+ const line1 = "line1\n";
+ const line2 = "line2\n";
+
+ var buf1: [line1.len]u8 = undefined;
+ var buf2: [line2.len]u8 = undefined;
+ var write_vecs = [_]std.os.iovec_const{
+ .{
+ .iov_base = line1,
+ .iov_len = line1.len,
+ },
+ .{
+ .iov_base = line2,
+ .iov_len = line2.len,
+ },
+ };
+ var read_vecs = [_]std.os.iovec{
+ .{
+ .iov_base = &buf2,
+ .iov_len = buf2.len,
+ },
+ .{
+ .iov_base = &buf1,
+ .iov_len = buf1.len,
+ },
+ };
+
+ var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
+ defer src_file.close();
+
+ try src_file.writevAll(&write_vecs);
+ try testing.expectEqual(@as(u64, line1.len + line2.len), try src_file.getEndPos());
+ try src_file.seekTo(0);
+ const read = try src_file.readvAll(&read_vecs);
+ try testing.expectEqual(@as(usize, line1.len + line2.len), read);
+ try testing.expectEqualStrings(&buf1, "line2\n");
+ try testing.expectEqualStrings(&buf2, "line1\n");
+}
+
+test "pwritev, preadv" {
+ var tmp = tmpDir(.{});
+ defer tmp.cleanup();
+
+ const line1 = "line1\n";
+ const line2 = "line2\n";
+
+ var buf1: [line1.len]u8 = undefined;
+ var buf2: [line2.len]u8 = undefined;
+ var write_vecs = [_]std.os.iovec_const{
+ .{
+ .iov_base = line1,
+ .iov_len = line1.len,
+ },
+ .{
+ .iov_base = line2,
+ .iov_len = line2.len,
+ },
+ };
+ var read_vecs = [_]std.os.iovec{
+ .{
+ .iov_base = &buf2,
+ .iov_len = buf2.len,
+ },
+ .{
+ .iov_base = &buf1,
+ .iov_len = buf1.len,
+ },
+ };
+
+ var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
+ defer src_file.close();
+
+ try src_file.pwritevAll(&write_vecs, 16);
+ try testing.expectEqual(@as(u64, 16 + line1.len + line2.len), try src_file.getEndPos());
+ const read = try src_file.preadvAll(&read_vecs, 16);
+ try testing.expectEqual(@as(usize, line1.len + line2.len), read);
+ try testing.expectEqualStrings(&buf1, "line2\n");
+ try testing.expectEqualStrings(&buf2, "line1\n");
+}
+
test "access file" {
if (builtin.os.tag == .wasi) return error.SkipZigTest;
lib/std/os.zig
@@ -646,8 +646,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
else
system.preadv;
+ const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
while (true) {
- const rc = preadv_sym(fd, iov.ptr, iov_count, offset);
+ const rc = preadv_sym(fd, iov.ptr, iov_count, ioffset);
switch (errno(rc)) {
0 => return @bitCast(usize, rc),
EINTR => continue,
@@ -998,8 +999,9 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
system.pwritev;
const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);
+ const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
while (true) {
- const rc = pwritev_sym(fd, iov.ptr, iov_count, offset);
+ const rc = pwritev_sym(fd, iov.ptr, iov_count, ioffset);
switch (errno(rc)) {
0 => return @intCast(usize, rc),
EINTR => continue,