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