Function copy_file_range [src]

Transfer data between file descriptors at specified offsets. Returns the number of bytes written, which can less than requested. The copy_file_range call copies len bytes from one file descriptor to another. When possible, this is done within the operating system kernel, which can provide better performance characteristics than transferring data from kernel to user space and back, such as with pread and pwrite calls. fd_in must be a file descriptor opened for reading, and fd_out must be a file descriptor opened for writing. They may be any kind of file descriptor; however, if fd_in is not a regular file system file, it may cause this function to fall back to calling pread and pwrite, in which case atomicity guarantees no longer apply. If fd_in and fd_out are the same, source and target ranges must not overlap. The file descriptor seek positions are ignored and not updated. When off_in is past the end of the input file, it successfully reads 0 bytes. flags has different meanings per operating system; refer to the respective man pages. These systems support in-kernel data copying: Linux (cross-filesystem from version 5.3) FreeBSD 13.0 Other systems fall back to calling pread / pwrite. Maximum offsets on Linux and FreeBSD are maxInt(i64).

Prototype

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

Parameters

fd_in: fd_toff_in: u64fd_out: fd_toff_out: u64len: usizeflags: u32

Possible Errors

AccessDenied ReadError

In WASI, this error occurs when the file descriptor does not hold the required rights to read from it.

BrokenPipe ReadError
Canceled ReadError

reading a timerfd with CANCEL_ON_SET will lead to this error when the clock goes through a discontinuous change

ConnectionResetByPeer WriteError

Connection reset by peer.

ConnectionTimedOut ReadError
CorruptedData
DeviceBusy WriteError
DiskQuota WriteError
FileTooBig
FilesOpenedWithWrongFlags

fd_in is not open for reading; or fd_out is not open for writing; or the APPEND flag is set for fd_out.

InputOutput
InvalidArgument WriteError
IsDir
LockViolation ReadError

Unable to read file due to lock.

MessageTooBig WriteError

The socket type requires that message be sent atomically, and the size of the message to be sent made this impossible. The message is not transmitted.

NoDevice WriteError

This error occurs when a device gets disconnected before or mid-flush while it's being written to - errno(6): No such device or address.

NoSpaceLeft
NotOpenForReading ReadError
NotOpenForWriting WriteError
OperationAborted ReadError
OutOfMemory
PermissionDenied
ProcessNotFound ReadError

This error occurs in Linux if the process to be read from no longer exists.

SocketNotConnected ReadError
SwapFile
SystemResources ReadError
Unexpected UnexpectedError

The Operating System returned an undocumented error code.

This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.

When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.

Unseekable
WouldBlock ReadError

This error occurs when no global event loop is configured, and reading from the file descriptor would block.

Source

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 ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or (comptime builtin.os.tag == .linux and std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }))) { 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); if (native_os == .freebsd) { switch (errno(rc)) { .SUCCESS => return @intCast(rc), .BADF => return error.FilesOpenedWithWrongFlags, .FBIG => return error.FileTooBig, .IO => return error.InputOutput, .ISDIR => return error.IsDir, .NOSPC => return error.NoSpaceLeft, .INVAL => break, // these may not be regular files, try fallback .INTEGRITY => return error.CorruptedData, .INTR => continue, else => |err| return unexpectedErrno(err), } } else { // assume linux switch (errno(rc)) { .SUCCESS => return @intCast(rc), .BADF => return error.FilesOpenedWithWrongFlags, .FBIG => return error.FileTooBig, .IO => return error.InputOutput, .ISDIR => return error.IsDir, .NOSPC => return error.NoSpaceLeft, .INVAL => break, // these may not be regular files, try fallback .NOMEM => return error.OutOfMemory, .OVERFLOW => return error.Unseekable, .PERM => return error.PermissionDenied, .TXTBSY => return error.SwapFile, .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback else => |err| return unexpectedErrno(err), } } } } var buf: [8 * 4096]u8 = undefined; const amt_read = try pread(fd_in, buf[0..@min(buf.len, len)], off_in); if (amt_read == 0) return 0; return pwrite(fd_out, buf[0..amt_read], off_out); }