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