From bc512648dbb27d895e69857202b22bc34d27f122 Mon Sep 17 00:00:00 2001 From: rpkak Date: Sun, 31 Aug 2025 10:56:09 +0200 Subject: [PATCH] use copy_file_range syscall on linux --- lib/std/fs/File.zig | 2 +- lib/std/os/linux.zig | 4 +++- lib/std/posix.zig | 10 ++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/std/fs/File.zig b/lib/std/fs/File.zig index a5a3955a24..99dda27885 100644 --- a/lib/std/fs/File.zig +++ b/lib/std/fs/File.zig @@ -1916,7 +1916,7 @@ pub const Writer = struct { const copy_file_range = switch (native_os) { .freebsd => std.os.freebsd.copy_file_range, - .linux => if (std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 })) std.os.linux.wrapped.copy_file_range else {}, + .linux => std.os.linux.wrapped.copy_file_range, else => {}, }; if (@TypeOf(copy_file_range) != void) cfr: { diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index ba2ab3c04f..1278128d21 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -9891,7 +9891,9 @@ pub const wrapped = struct { }; pub fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_out: ?*i64, len: usize, flags: u32) CopyFileRangeError!usize { - const rc = system.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags); + const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 }); + const sys = if (use_c) std.c else std.os.linux; + const rc = sys.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags); switch (errno(rc)) { .SUCCESS => return @intCast(rc), .BADF => return error.BadFileFlags, diff --git a/lib/std/posix.zig b/lib/std/posix.zig index abedcaf704..67d337a081 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -6515,14 +6515,16 @@ pub const CopyFileRangeError = error{ /// /// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`. 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 { - if (builtin.os.tag == .freebsd or - (comptime builtin.os.tag == .linux and std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 }))) - { + if (builtin.os.tag == .freebsd or builtin.os.tag == .linux) { + const use_c = native_os != .linux or + std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 }); + const sys = if (use_c) std.c else linux; + var off_in_copy: i64 = @bitCast(off_in); var off_out_copy: i64 = @bitCast(off_out); while (true) { - const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); + const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); if (native_os == .freebsd) { switch (errno(rc)) { .SUCCESS => return @intCast(rc),