fn sendfile(out_fd: fd_t, in_fd: fd_t, in_offset: u64, in_len: u64, headers: []const iovec_const, trailers: []const iovec_const, flags: u32) SendFileError!usize

Transfer data between file descriptors, with optional headers and trailers. Returns the number of bytes written, which can be zero.

The sendfile call copies in_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 read and write calls. When in_len is 0, it means to copy until the end of the input file has been reached. Note, however, that partial writes are still possible in this case.

in_fd must be a file descriptor opened for reading, and out_fd must be a file descriptor opened for writing. They may be any kind of file descriptor; however, if in_fd is not a regular file system file, it may cause this function to fall back to calling read and write, in which case atomicity guarantees no longer apply.

Copying begins reading at in_offset. The input file descriptor seek position is ignored and not updated. If the output file descriptor has a seek position, it is updated as bytes are written. When in_offset 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 atomically sending everything, including headers and trailers:

  • macOS
  • FreeBSD

These systems support in-kernel data copying, but headers and trailers are not sent atomically:

  • Linux

Other systems fall back to calling read / write.

Linux has a limit on how many bytes may be transferred in one sendfile call, which is 0x7ffff000 on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as well as stuffing the errno codes into the last 4096 values. This is noted on the sendfile man page. The limit on Darwin is 0x7fffffff, trying to write more than that returns EINVAL. The corresponding POSIX limit on this is math.maxInt(isize).

Parameters

out_fd: fd_t,
in_fd: fd_t,
in_offset: u64,
in_len: u64,
headers: []const iovec_const,
trailers: []const iovec_const,
flags: u32,