| ... | ... | @@ -4945,7 +4945,9 @@ pub fn sendfile( |
| 4945 | 4945 | pub const CopyFileRangeError = error{ |
| 4946 | 4946 | FileTooBig, |
| 4947 | 4947 | InputOutput, |
| 4948 | | InvalidFileDescriptor, |
| 4948 | /// `fd_in` is not open for reading; or `fd_out` is not open for writing; |
| 4949 | /// or the `O_APPEND` flag is set for `fd_out`. |
| 4950 | FilesOpenedWithWrongFlags, |
| 4949 | 4951 | IsDir, |
| 4950 | 4952 | OutOfMemory, |
| 4951 | 4953 | NoSpaceLeft, |
| ... | ... | @@ -4955,7 +4957,7 @@ pub const CopyFileRangeError = error{ |
| 4955 | 4957 | } || PReadError || PWriteError || UnexpectedError; |
| 4956 | 4958 | |
| 4957 | 4959 | var has_copy_file_range_syscall = init: { |
| 4958 | | const kernel_has_syscall = comptime std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; |
| 4960 | const kernel_has_syscall = std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; |
| 4959 | 4961 | break :init std.atomic.Int(bool).init(kernel_has_syscall); |
| 4960 | 4962 | }; |
| 4961 | 4963 | |
| ... | ... | @@ -4998,7 +5000,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len |
| 4998 | 5000 | const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); |
| 4999 | 5001 | switch (sys.getErrno(rc)) { |
| 5000 | 5002 | 0 => return @intCast(usize, rc), |
| 5001 | | EBADF => return error.InvalidFileDescriptor, |
| 5003 | EBADF => return error.FilesOpenedWithWrongFlags, |
| 5002 | 5004 | EFBIG => return error.FileTooBig, |
| 5003 | 5005 | EIO => return error.InputOutput, |
| 5004 | 5006 | 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 |
| 5019 | 5021 | } |
| 5020 | 5022 | } |
| 5021 | 5023 | |
| 5022 | | var buf: [2 * 4096]u8 = undefined; |
| 5023 | | |
| 5024 | | var total_copied: usize = 0; |
| 5025 | | var read_off = off_in; |
| 5026 | | var write_off = off_out; |
| 5027 | | while (total_copied < len) { |
| 5028 | | const adjusted_count = math.min(buf.len, len - total_copied); |
| 5029 | | const amt_read = try pread(fd_in, buf[0..adjusted_count], read_off); |
| 5030 | | if (amt_read == 0) break; |
| 5031 | | const amt_written = try pwrite(fd_out, buf[0..amt_read], write_off); |
| 5032 | | // pwrite may write less than the specified amount, handle the remaining |
| 5033 | | // chunk of data in the next iteration |
| 5034 | | read_off += amt_written; |
| 5035 | | write_off += amt_written; |
| 5036 | | total_copied += amt_written; |
| 5037 | | } |
| 5038 | | |
| 5039 | | return total_copied; |
| 5024 | var buf: [8 * 4096]u8 = undefined; |
| 5025 | const adjusted_count = math.min(buf.len, len); |
| 5026 | const amt_read = try pread(fd_in, buf[0..adjusted_count], off_in); |
| 5027 | // TODO without @as the line below fails to compile for wasm32-wasi: |
| 5028 | // error: integer value 0 cannot be coerced to type 'os.PWriteError!usize' |
| 5029 | if (amt_read == 0) return @as(usize, 0); |
| 5030 | return pwrite(fd_out, buf[0..amt_read], off_out); |
| 5040 | 5031 | } |
| 5041 | 5032 | |
| 5042 | 5033 | pub const PollError = error{ |