| ... | ... | @@ -5542,10 +5542,7 @@ pub const CopyFileRangeError = error{ |
| 5542 | 5542 | FileBusy, |
| 5543 | 5543 | } || PReadError || PWriteError || UnexpectedError; |
| 5544 | 5544 | |
| 5545 | | var has_copy_file_range_syscall = init: { |
| 5546 | | const kernel_has_syscall = std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; |
| 5547 | | break :init std.atomic.Atomic(bool).init(kernel_has_syscall); |
| 5548 | | }; |
| 5545 | var has_copy_file_range_syscall = std.atomic.Atomic(bool).init(true); |
| 5549 | 5546 | |
| 5550 | 5547 | /// Transfer data between file descriptors at specified offsets. |
| 5551 | 5548 | /// Returns the number of bytes written, which can less than requested. |
| ... | ... | @@ -5573,18 +5570,17 @@ var has_copy_file_range_syscall = init: { |
| 5573 | 5570 | /// |
| 5574 | 5571 | /// Maximum offsets on Linux are `math.maxInt(i64)`. |
| 5575 | 5572 | 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 { |
| 5576 | | const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; |
| 5577 | | |
| 5578 | | if (std.Target.current.os.tag == .linux and |
| 5579 | | (use_c or has_copy_file_range_syscall.load(.Monotonic))) |
| 5580 | | { |
| 5581 | | const sys = if (use_c) std.c else linux; |
| 5573 | const call_cfr = comptime if (builtin.link_libc) |
| 5574 | std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok |
| 5575 | else |
| 5576 | std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; |
| 5582 | 5577 | |
| 5578 | if (call_cfr and has_copy_file_range_syscall.load(.Monotonic)) { |
| 5583 | 5579 | var off_in_copy = @bitCast(i64, off_in); |
| 5584 | 5580 | var off_out_copy = @bitCast(i64, off_out); |
| 5585 | 5581 | |
| 5586 | | const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); |
| 5587 | | switch (sys.getErrno(rc)) { |
| 5582 | const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); |
| 5583 | switch (system.getErrno(rc)) { |
| 5588 | 5584 | 0 => return @intCast(usize, rc), |
| 5589 | 5585 | EBADF => return error.FilesOpenedWithWrongFlags, |
| 5590 | 5586 | EFBIG => return error.FileTooBig, |
| ... | ... | @@ -5601,7 +5597,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len |
| 5601 | 5597 | EXDEV => {}, |
| 5602 | 5598 | // syscall added in Linux 4.5, use fallback |
| 5603 | 5599 | ENOSYS => { |
| 5604 | | has_copy_file_range_syscall.store(true, .Monotonic); |
| 5600 | has_copy_file_range_syscall.store(false, .Monotonic); |
| 5605 | 5601 | }, |
| 5606 | 5602 | else => |err| return unexpectedErrno(err), |
| 5607 | 5603 | } |