| ... | @@ -5532,10 +5532,7 @@ pub const CopyFileRangeError = error{ | ... | @@ -5532,10 +5532,7 @@ pub const CopyFileRangeError = error{ |
| 5532 | FileBusy, | 5532 | FileBusy, |
| 5533 | } || PReadError || PWriteError || UnexpectedError; | 5533 | } || PReadError || PWriteError || UnexpectedError; |
| 5534 | | 5534 | |
| 5535 | var has_copy_file_range_syscall = init: { | 5535 | var has_copy_file_range_syscall = std.atomic.Atomic(bool).init(true); |
| 5536 | const kernel_has_syscall = std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; | | |
| 5537 | break :init std.atomic.Atomic(bool).init(kernel_has_syscall); | | |
| 5538 | }; | | |
| 5539 | | 5536 | |
| 5540 | /// Transfer data between file descriptors at specified offsets. | 5537 | /// Transfer data between file descriptors at specified offsets. |
| 5541 | /// Returns the number of bytes written, which can less than requested. | 5538 | /// Returns the number of bytes written, which can less than requested. |
| ... | @@ -5563,18 +5560,17 @@ var has_copy_file_range_syscall = init: { | ... | @@ -5563,18 +5560,17 @@ var has_copy_file_range_syscall = init: { |
| 5563 | /// | 5560 | /// |
| 5564 | /// Maximum offsets on Linux are `math.maxInt(i64)`. | 5561 | /// Maximum offsets on Linux are `math.maxInt(i64)`. |
| 5565 | pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize { | 5562 | pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize { |
| 5566 | const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; | 5563 | const call_cfr = comptime if (builtin.link_libc) |
| 5567 | | 5564 | std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok |
| 5568 | if (std.Target.current.os.tag == .linux and | 5565 | else |
| 5569 | (use_c or has_copy_file_range_syscall.load(.Monotonic))) | 5566 | std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; |
| 5570 | { | | |
| 5571 | const sys = if (use_c) std.c else linux; | | |
| 5572 | | 5567 | |
| | 5568 | if (call_cfr and has_copy_file_range_syscall.load(.Monotonic)) { |
| 5573 | var off_in_copy = @bitCast(i64, off_in); | 5569 | var off_in_copy = @bitCast(i64, off_in); |
| 5574 | var off_out_copy = @bitCast(i64, off_out); | 5570 | var off_out_copy = @bitCast(i64, off_out); |
| 5575 | | 5571 | |
| 5576 | const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); | 5572 | const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); |
| 5577 | switch (sys.getErrno(rc)) { | 5573 | switch (system.getErrno(rc)) { |
| 5578 | 0 => return @intCast(usize, rc), | 5574 | 0 => return @intCast(usize, rc), |
| 5579 | EBADF => return error.FilesOpenedWithWrongFlags, | 5575 | EBADF => return error.FilesOpenedWithWrongFlags, |
| 5580 | EFBIG => return error.FileTooBig, | 5576 | EFBIG => return error.FileTooBig, |
| ... | @@ -5591,7 +5587,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len | ... | @@ -5591,7 +5587,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len |
| 5591 | EXDEV => {}, | 5587 | EXDEV => {}, |
| 5592 | // syscall added in Linux 4.5, use fallback | 5588 | // syscall added in Linux 4.5, use fallback |
| 5593 | ENOSYS => { | 5589 | ENOSYS => { |
| 5594 | has_copy_file_range_syscall.store(true, .Monotonic); | 5590 | has_copy_file_range_syscall.store(false, .Monotonic); |
| 5595 | }, | 5591 | }, |
| 5596 | else => |err| return unexpectedErrno(err), | 5592 | else => |err| return unexpectedErrno(err), |
| 5597 | } | 5593 | } |