From 03762da2af8753ecf7f4bc2005dd00d570c51ae7 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 7 Oct 2020 11:13:26 +0200 Subject: New review round --- lib/std/c/darwin.zig | 2 -- lib/std/fs.zig | 5 +++-- lib/std/os.zig | 33 ++++++++++++--------------------- 3 files changed, 15 insertions(+), 25 deletions(-) (limited to 'lib/std') diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 5b305d60e6..93efdd061c 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -24,8 +24,6 @@ pub const COPYFILE_XATTR = 1 << 2; pub const COPYFILE_DATA = 1 << 3; pub const copyfile_state_t = *@Type(.Opaque); -pub extern "c" fn copyfile_state_alloc() copyfile_state_t; -pub extern "c" fn copyfile_state_free(state: copyfile_state_t) c_int; pub extern "c" fn fcopyfile(from: fd_t, to: fd_t, state: ?copyfile_state_t, flags: u32) c_int; pub extern "c" fn @"realpath$DARWIN_EXTSN"(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 6b4f9384dd..5f49bb3766 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -2265,8 +2265,9 @@ pub fn realpathAlloc(allocator: *Allocator, pathname: []const u8) ![]u8 { const CopyFileError = error{SystemResources} || os.CopyFileRangeError || os.SendFileError; -/// Transfer all the data between two file descriptors in the most efficient way. -/// No metadata is transferred over. +// Transfer all the data between two file descriptors in the most efficient way. +// The copy starts at offset 0, the initial offsets are preserved. +// No metadata is transferred over. fn copy_file(fd_in: os.fd_t, fd_out: os.fd_t) CopyFileError!void { if (comptime std.Target.current.isDarwin()) { const rc = os.system.fcopyfile(fd_in, fd_out, null, os.system.COPYFILE_DATA); diff --git a/lib/std/os.zig b/lib/std/os.zig index 0e81b73f8c..6e25451879 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -4945,7 +4945,9 @@ pub fn sendfile( pub const CopyFileRangeError = error{ FileTooBig, InputOutput, - InvalidFileDescriptor, + /// `fd_in` is not open for reading; or `fd_out` is not open for writing; + /// or the `O_APPEND` flag is set for `fd_out`. + FilesOpenedWithWrongFlags, IsDir, OutOfMemory, NoSpaceLeft, @@ -4955,7 +4957,7 @@ pub const CopyFileRangeError = error{ } || PReadError || PWriteError || UnexpectedError; var has_copy_file_range_syscall = init: { - const kernel_has_syscall = comptime std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; + const kernel_has_syscall = std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; break :init std.atomic.Int(bool).init(kernel_has_syscall); }; @@ -4998,7 +5000,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); switch (sys.getErrno(rc)) { 0 => return @intCast(usize, rc), - EBADF => return error.InvalidFileDescriptor, + EBADF => return error.FilesOpenedWithWrongFlags, EFBIG => return error.FileTooBig, EIO => return error.InputOutput, EISDIR => return error.IsDir, @@ -5019,24 +5021,13 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len } } - var buf: [2 * 4096]u8 = undefined; - - var total_copied: usize = 0; - var read_off = off_in; - var write_off = off_out; - while (total_copied < len) { - const adjusted_count = math.min(buf.len, len - total_copied); - const amt_read = try pread(fd_in, buf[0..adjusted_count], read_off); - if (amt_read == 0) break; - const amt_written = try pwrite(fd_out, buf[0..amt_read], write_off); - // pwrite may write less than the specified amount, handle the remaining - // chunk of data in the next iteration - read_off += amt_written; - write_off += amt_written; - total_copied += amt_written; - } - - return total_copied; + var buf: [8 * 4096]u8 = undefined; + const adjusted_count = math.min(buf.len, len); + const amt_read = try pread(fd_in, buf[0..adjusted_count], off_in); + // TODO without @as the line below fails to compile for wasm32-wasi: + // error: integer value 0 cannot be coerced to type 'os.PWriteError!usize' + if (amt_read == 0) return @as(usize, 0); + return pwrite(fd_out, buf[0..amt_read], off_out); } pub const PollError = error{ -- cgit v1.2.3