copy_file_range
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).
Function parameters
Parameters
Type definitions in this namespace
Types
Obtains errno from the return value of a system function call.
Functions
- errno
- Obtains errno from the return value of a system function call.
- close
- Closes the file descriptor.
- fchmod
- Changes the mode of the file referred to by the file descriptor.
- fchmodat
- Changes the `mode` of `path` relative to the directory referred to by
- fchown
- Changes the owner and group of the file referred to by the file descriptor.
- getrandom
- Obtain a series of random bytes.
- abort
- Causes abnormal process termination.
- exit
- Exits all threads of the program with the specified status code.
- read
- Returns the number of bytes that were read, which can be less than
- readv
- Number of bytes read is returned.
- pread
- Number of bytes read is returned.
- ftruncate
- Length must be positive when treated as an i64.
- preadv
- Number of bytes read is returned.
- write
- Write to a file descriptor.
- writev
- Write multiple buffers to a file descriptor.
- pwrite
- Write to a file descriptor, with a position offset.
- pwritev
- Write multiple buffers to a file descriptor, with a position offset.
- open
- Open and possibly create a file.
- openZ
- Open and possibly create a file.
- openat
- Open and possibly create a file.
- openatWasi
- Open and possibly create a file in WASI.
- openatZ
- Open and possibly create a file.
- execveZ
- This function ignores PATH environment variable.
- execvpeZ_expandArg0
- Like `execvpeZ` except if `arg0_expand` is `.expand`, then `argv` is mutable,
- execvpeZ
- This function also uses the PATH environment variable to get the full path to the executable.
- getenv
- Get an environment variable.
- getenvZ
- Get an environment variable with a null-terminated name.
- getcwd
- The result is a slice of out_buffer, indexed from 0.
- symlink
- Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
- symlinkZ
- This is the same as `symlink` except the parameters are null-terminated pointers.
- symlinkat
- Similar to `symlink`, however, creates a symbolic link named `sym_link_path` which contains the string
- symlinkatWasi
- WASI-only.
- symlinkatZ
- The same as `symlinkat` except the parameters are null-terminated pointers.
- linkZ
- On WASI, both paths should be encoded as valid UTF-8.
- link
- On WASI, both paths should be encoded as valid UTF-8.
- linkatZ
- On WASI, both paths should be encoded as valid UTF-8.
- linkat
- On WASI, both paths should be encoded as valid UTF-8.
- unlink
- Delete a name and possibly the file it refers to.
- unlinkZ
- Same as `unlink` except the parameter is null terminated.
- unlinkW
- Windows-only.
- unlinkat
- Delete a file name and possibly the file it refers to, based on an open directory handle.
- unlinkatWasi
- WASI-only.
- unlinkatZ
- Same as `unlinkat` but `file_path` is a null-terminated string.
- unlinkatW
- Same as `unlinkat` but `sub_path_w` is WTF16LE, NT prefixed.
- rename
- Change the name or location of a file.
- renameZ
- Same as `rename` except the parameters are null-terminated.
- renameW
- Same as `rename` except the parameters are null-terminated and WTF16LE encoded.
- renameat
- Change the name or location of a file based on an open directory handle.
- renameatZ
- Same as `renameat` except the parameters are null-terminated.
- renameatW
- Same as `renameat` but Windows-only and the path parameters are
- mkdirat
- On Windows, `sub_dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
- mkdiratZ
- Same as `mkdirat` except the parameters are null-terminated.
- mkdiratW
- Windows-only.
- mkdir
- Create a directory.
- mkdirZ
- Same as `mkdir` but the parameter is null-terminated.
- mkdirW
- Windows-only.
- rmdir
- Deletes an empty directory.
- rmdirZ
- Same as `rmdir` except the parameter is null-terminated.
- rmdirW
- Windows-only.
- chdir
- Changes the current working directory of the calling process.
- chdirZ
- Same as `chdir` except the parameter is null-terminated.
- chdirW
- Windows-only.
- readlink
- Read value of a symbolic link.
- readlinkW
- Windows-only.
- readlinkZ
- Same as `readlink` except `file_path` is null-terminated.
- readlinkat
- Similar to `readlink` except reads value of a symbolink link **relative** to `dirfd` directory handle.
- readlinkatWasi
- WASI-only.
- readlinkatW
- Windows-only.
- readlinkatZ
- Same as `readlinkat` except `file_path` is null-terminated.
- isatty
- Test whether a file descriptor refers to a terminal.
- shutdown
- Shutdown socket send/receive operations
- bind
- addr is `*const T` where T is one of the sockaddr
- accept
- Accept a connection on a socket.
- epoll_wait
- Waits for an I/O event on an epoll file descriptor.
- connect
- Initiate a connection on a socket.
- waitpid
- Use this version of the `waitpid` wrapper if you spawned your child process using explicit
- fstat
- Return information about a file descriptor.
- fstatat
- Similar to `fstat`, but returns stat of a resource pointed to by `pathname`
- fstatatZ
- Same as `fstatat` but `pathname` is null-terminated.
- inotify_init1
- initialize an inotify instance
- inotify_add_watch
- add a watch to an initialized inotify instance
- inotify_add_watchZ
- Same as `inotify_add_watch` except pathname is null-terminated.
- inotify_rm_watch
- remove an existing watch from an inotify instance
- mmap
- Map files or devices into memory.
- munmap
- Deletes the mappings for the specified address range, causing
- access
- check user's permissions for a file
- accessZ
- Same as `access` except `path` is null-terminated.
- faccessat
- Check user's permissions for a file, based on an open directory handle.
- faccessatZ
- Same as `faccessat` except the path parameter is null-terminated.
- faccessatW
- Same as `faccessat` except asserts the target is Windows and the path parameter
- pipe
- Creates a unidirectional data channel that can be used for interprocess communication.
- lseek_SET
- Repositions read/write file offset relative to the beginning.
- lseek_CUR
- Repositions read/write file offset relative to the current offset.
- lseek_END
- Repositions read/write file offset relative to the end.
- lseek_CUR_get
- Returns the read/write file offset relative to the beginning.
- flock
- Depending on the operating system `flock` may or may not interact with
- realpath
- Return the canonicalized absolute pathname.
- realpathZ
- Same as `realpath` except `pathname` is null-terminated.
- realpathW
- Same as `realpath` except `pathname` is WTF16LE-encoded.
- nanosleep
- Spurious wakeups are possible and no precision of timing is guaranteed.
- sigfillset
- Return a filled sigset_t.
- sigemptyset
- Return an empty sigset_t.
- sigaction
- Examine and change a signal action.
- sigprocmask
- Sets the thread signal mask.
- sendto
- Transmit a message to another socket.
- send
- Transmit a message to another socket.
- copy_file_range
- Transfer data between file descriptors at specified offsets.
- recvfrom
- If `sockfd` is opened in non blocking mode, the function will
- setsockopt
- Set a socket's options.
- tcgetpgrp
- Returns the process group ID for the TTY associated with the given handle.
- tcsetpgrp
- Sets the controlling process group ID for given TTY.
- sync
- Write all pending file contents and metadata modifications to all filesystems.
- syncfs
- Write all pending file contents and metadata modifications to the filesystem which contains the specified file.
- fsync
- Write all pending file contents and metadata modifications for the specified file descriptor to the underlying filesystem.
- fdatasync
- Write all pending file contents for the specified file descriptor to the underlying filesystem, but not necessarily the metadata.
- mincore
- Determine whether pages are resident in memory.
- madvise
- Give advice about use of memory.
- unexpectedErrno
- Call this when you made a syscall or something that sets errno
- toPosixPath
- Used to convert a slice to a null terminated slice on the stack.
Error sets in this namespace
Error Sets
= system.AF
Values
- AF
- = system.AF
- AF_SUN
- = system.AF_SUN
- AI
- = system.AI
- ARCH
- = system.ARCH
- AT
- = system.AT
- AT_SUN
- = system.AT_SUN
- CLOCK
- = system.CLOCK
- CPU_COUNT
- = system.CPU_COUNT
- CTL
- = system.CTL
- DT
- = system.DT
- E
- = system.E
- Elf_Symndx
- = system.Elf_Symndx
- F
- = system.F
- FD_CLOEXEC
- = system.FD_CLOEXEC
- Flock
- = system.Flock
- HOST_NAME_MAX
- = system.HOST_NAME_MAX
- HW
- = system.HW
- IFNAMESIZE
- = system.IFNAMESIZE
- IOV_MAX
- = system.IOV_MAX
- IPPROTO
- = system.IPPROTO
- KERN
- = system.KERN
- Kevent
- = system.Kevent
- MADV
- = system.MADV
- MAP
- = system.MAP
- MAX_ADDR_LEN
- = system.MAX_ADDR_LEN
- MFD
- = system.MFD
- MREMAP
- = system.MREMAP
- MSF
- = system.MSF
- MSG
- = system.MSG
- NAME_MAX
- = system.NAME_MAX
- NSIG
- = system.NSIG
- O
- = system.O
- PATH_MAX
- = system.PATH_MAX
- POLL
- = system.POLL
- POSIX_FADV
- = system.POSIX_FADV
- PR
- = system.PR
- PROT
- = system.PROT
- REG
- = system.REG
- RLIM
- = system.RLIM
- RR
- = system.RR
- S
- = system.S
- SA
- = system.SA
- SC
- = system.SC
- SEEK
- = system.SEEK
- SHUT
- = system.SHUT
- SIG
- = system.SIG
- SIOCGIFINDEX
- = system.SIOCGIFINDEX
- SO
- = system.SO
- SOCK
- = system.SOCK
- SOL
- = system.SOL
- IFF
- = system.IFF
- STDERR_FILENO
- = system.STDERR_FILENO
- STDIN_FILENO
- = system.STDIN_FILENO
- STDOUT_FILENO
- = system.STDOUT_FILENO
- SYS
- = system.SYS
- Sigaction
- = system.Sigaction
- Stat
- = system.Stat
- T
- = system.T
- TCP
- = system.TCP
- VDSO
- = system.VDSO
- W
- = system.W
- _SC
- = system._SC
- addrinfo
- = system.addrinfo
- blkcnt_t
- = system.blkcnt_t
- blksize_t
- = system.blksize_t
- clock_t
- = system.clock_t
- clockid_t
- = system.clockid_t
- timerfd_clockid_t
- = system.timerfd_clockid_t
- cpu_set_t
- = system.cpu_set_t
- dev_t
- = system.dev_t
- dl_phdr_info
- = system.dl_phdr_info
- fd_t
- = system.fd_t
- file_obj
- = system.file_obj
- gid_t
- = system.gid_t
- ifreq
- = system.ifreq
- ino_t
- = system.ino_t
- mcontext_t
- = system.mcontext_t
- mode_t
- = system.mode_t
- msghdr
- = system.msghdr
- msghdr_const
- = system.msghdr_const
- nfds_t
- = system.nfds_t
- nlink_t
- = system.nlink_t
- off_t
- = system.off_t
- pid_t
- = system.pid_t
- pollfd
- = system.pollfd
- port_event
- = system.port_event
- port_notify
- = system.port_notify
- port_t
- = system.port_t
- rlim_t
- = system.rlim_t
- rlimit
- = system.rlimit
- rlimit_resource
- = system.rlimit_resource
- rusage
- = system.rusage
- sa_family_t
- = system.sa_family_t
- siginfo_t
- = system.siginfo_t
- sigset_t
- = system.sigset_t
- sigrtmin
- = system.sigrtmin
- sigrtmax
- = system.sigrtmax
- sockaddr
- = system.sockaddr
- socklen_t
- = system.socklen_t
- stack_t
- = system.stack_t
- time_t
- = system.time_t
- timespec
- = system.timespec
- timestamp_t
- = system.timestamp_t
- timeval
- = system.timeval
- timezone
- = system.timezone
- ucontext_t
- = system.ucontext_t
- uid_t
- = system.uid_t
- user_desc
- = system.user_desc
- utsname
- = system.utsname
- termios
- = system.termios
- CSIZE
- = system.CSIZE
- NCCS
- = system.NCCS
- cc_t
- = system.cc_t
- V
- = system.V
- speed_t
- = system.speed_t
- tc_iflag_t
- = system.tc_iflag_t
- tc_oflag_t
- = system.tc_oflag_t
- tc_cflag_t
- = system.tc_cflag_t
- tc_lflag_t
- = system.tc_lflag_t
- F_OK
- = system.F_OK
- R_OK
- = system.R_OK
- W_OK
- = system.W_OK
- X_OK
- = system.X_OK
- unexpected_error_tracing
- Whether or not `error.Unexpected` will print its value and a stack trace.
Source
Implementation
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 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 = 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),
.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);
}