| ... | @@ -4954,6 +4954,11 @@ pub const CopyFileRangeError = error{ | ... | @@ -4954,6 +4954,11 @@ pub const CopyFileRangeError = error{ |
| 4954 | FileBusy, | 4954 | FileBusy, |
| 4955 | } || PReadError || PWriteError || UnexpectedError; | 4955 | } || PReadError || PWriteError || UnexpectedError; |
| 4956 | | 4956 | |
| | 4957 | 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; |
| | 4959 | break :init std.atomic.Int(bool).init(kernel_has_syscall); |
| | 4960 | }; |
| | 4961 | |
| 4957 | /// Transfer data between file descriptors at specified offsets. | 4962 | /// Transfer data between file descriptors at specified offsets. |
| 4958 | /// Returns the number of bytes written, which can less than requested. | 4963 | /// Returns the number of bytes written, which can less than requested. |
| 4959 | /// | 4964 | /// |
| ... | @@ -4979,16 +4984,11 @@ pub const CopyFileRangeError = error{ | ... | @@ -4979,16 +4984,11 @@ pub const CopyFileRangeError = error{ |
| 4979 | /// Other systems fall back to calling `pread` / `pwrite`. | 4984 | /// Other systems fall back to calling `pread` / `pwrite`. |
| 4980 | /// | 4985 | /// |
| 4981 | /// Maximum offsets on Linux are `math.maxInt(i64)`. | 4986 | /// Maximum offsets on Linux are `math.maxInt(i64)`. |
| 4982 | var has_copy_file_range_syscall = init: { | | |
| 4983 | const kernel_has_syscall = comptime std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; | | |
| 4984 | break :init std.atomic.Int(u1).init(@boolToInt(kernel_has_syscall)); | | |
| 4985 | }; | | |
| 4986 | | | |
| 4987 | 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 { | 4987 | 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 { |
| 4988 | const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; | 4988 | const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; |
| 4989 | | 4989 | |
| 4990 | if (std.Target.current.os.tag == .linux and | 4990 | if (std.Target.current.os.tag == .linux and |
| 4991 | (use_c or has_copy_file_range_syscall.get() != 0)) | 4991 | (use_c or has_copy_file_range_syscall.get())) |
| 4992 | { | 4992 | { |
| 4993 | const sys = if (use_c) std.c else linux; | 4993 | const sys = if (use_c) std.c else linux; |
| 4994 | | 4994 | |
| ... | @@ -5013,7 +5013,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len | ... | @@ -5013,7 +5013,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len |
| 5013 | EXDEV => {}, | 5013 | EXDEV => {}, |
| 5014 | // syscall added in Linux 4.5, use fallback | 5014 | // syscall added in Linux 4.5, use fallback |
| 5015 | ENOSYS => { | 5015 | ENOSYS => { |
| 5016 | has_copy_file_range_syscall.set(0); | 5016 | has_copy_file_range_syscall.set(false); |
| 5017 | }, | 5017 | }, |
| 5018 | else => |err| return unexpectedErrno(err), | 5018 | else => |err| return unexpectedErrno(err), |
| 5019 | } | 5019 | } |