use copy_file_range syscall on linux
This commit is contained in:
committed by
Alex Rønne Petersen
parent
6069f908e9
commit
bc567312bf
@@ -1967,7 +1967,7 @@ pub const Writer = struct {
|
|||||||
|
|
||||||
const copy_file_range = switch (native_os) {
|
const copy_file_range = switch (native_os) {
|
||||||
.freebsd => std.os.freebsd.copy_file_range,
|
.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 => {},
|
else => {},
|
||||||
};
|
};
|
||||||
if (@TypeOf(copy_file_range) != void) cfr: {
|
if (@TypeOf(copy_file_range) != void) cfr: {
|
||||||
|
|||||||
@@ -9802,7 +9802,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 {
|
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)) {
|
switch (errno(rc)) {
|
||||||
.SUCCESS => return @intCast(rc),
|
.SUCCESS => return @intCast(rc),
|
||||||
.BADF => return error.BadFileFlags,
|
.BADF => return error.BadFileFlags,
|
||||||
|
|||||||
@@ -6387,14 +6387,16 @@ pub const CopyFileRangeError = error{
|
|||||||
///
|
///
|
||||||
/// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`.
|
/// 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 {
|
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
|
if (builtin.os.tag == .freebsd or builtin.os.tag == .linux) {
|
||||||
(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 })))
|
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_in_copy: i64 = @bitCast(off_in);
|
||||||
var off_out_copy: i64 = @bitCast(off_out);
|
var off_out_copy: i64 = @bitCast(off_out);
|
||||||
|
|
||||||
while (true) {
|
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) {
|
if (native_os == .freebsd) {
|
||||||
switch (errno(rc)) {
|
switch (errno(rc)) {
|
||||||
.SUCCESS => return @intCast(rc),
|
.SUCCESS => return @intCast(rc),
|
||||||
|
|||||||
Reference in New Issue
Block a user