sendfile(2)
โจ sendfile(2) โ System Calls Manual โจ
okay bestie, welcome to sendfile ๐ it's a system call, it lives in section 2, and honestly it's the moment when you stop doing the whole read-then-write two-step and just let the kernel handle it. icon behaviour only.
๐ธ NAME ๐ธ
sendfile โ transfer data between file descriptors. yes literally that's it, that's the whole job, slay ๐
๐ LIBRARY ๐
Standard C library (libc, -lc). so like, link it and go ๐
๐ฆ SYNOPSIS ๐ฆ
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *_Nullable offset,
size_t count);
๐ DESCRIPTION ๐
sendfile() copies data between one file descriptor and another. and here's the tea: because this copying happens inside the kernel, sendfile() is way more efficient than gluing together read(2) and write(2), which would make you shuttle all the data back and forth through user space. not me doing extra work for no reason ๐
in_fd should be a file descriptor opened for reading and out_fd should be a descriptor opened for writing. that's the vibe check.
If offset is not NULL, then it points to a variable holding the file offset from which sendfile() will start reading data from in_fd. and when sendfile() returns, that variable gets set to the offset of the byte following the last byte that was read. also: if offset is not NULL, then sendfile() does not touch the file offset of in_fd. but if offset is NULL, the file offset gets adjusted to reflect the number of bytes read from in_fd. periodt.
If offset is NULL, then data will be read from in_fd starting at the file offset, and the file offset will be updated by the call. yes, that's the same thing said twice, no, we're not skipping anything, every detail stays ๐ค
count is the number of bytes to copy between the file descriptors.
The in_fd argument must correspond to a file which supports mmap(2)-like operations โ meaning it cannot be a socket. huge. except, since Linux 5.12 and if out_fd is a pipe, in which case sendfile() desugars to a splice(2) and its restrictions apply. plot twist ๐
Before Linux 2.6.33, out_fd must refer to a socket. Since Linux 2.6.33 it can be any file. If it's seekable, then sendfile() changes the file offset appropriately. glow up fr fr โจ
๐ RETURN VALUE ๐
If the transfer was successful, the number of bytes written to out_fd is returned.
โ ๏ธ but bestie, listen โ a successful call to sendfile() may still write fewer bytes than requested. the caller should be prepared to retry the call if there were unsent bytes. see also NOTES. this is not a drill ๐ญ
On error, -1 is returned, and errno is set to indicate the error.
๐ ERRORS ๐
EAGAINโ Nonblocking I/O has been selected usingO_NONBLOCKand the write would block. it's giving "not right now" ๐EBADFโ The input file was not opened for reading or the output file was not opened for writing. one of them didn't have the right permissions, embarrassing.EFAULTโ Bad address.EINVALโ Descriptor is not valid or locked, or anmmap(2)-like operation is not available forin_fd, orcountis negative.EINVALโout_fdhas theO_APPENDflag set. This is not currently supported bysendfile(). so don't do that ๐ซถEIOโ Unspecified error while reading fromin_fd.ENOMEMโ Insufficient memory to read fromin_fd. brain empty, no thoughts, no memory ๐ญEOVERFLOWโcountis too large, the operation would result in exceeding the maximum size of either the input file or the output file.ESPIPEโoffsetis notNULLbut the input file is not seekable.
๐ง VERSIONS ๐ง
Other UNIX systems implement sendfile() with different semantics and prototypes. It should not be used in portable programs. that's the fine print and we respect it ๐
โญ STANDARDS โญ
None. literally none. it's built different, no standard to its name ๐
๐ HISTORY ๐
Linux 2.2, glibc 2.1.
In Linux 2.4 and earlier, out_fd could also refer to a regular file; this possibility went away in the Linux 2.6.x kernel series, but was restored in Linux 2.6.33. the comeback era ๐
The original Linux sendfile() system call was not designed to handle large file offsets. Consequently, Linux 2.4 added sendfile64(), with a wider type for the offset argument. The glibc sendfile() wrapper function transparently deals with the kernel differences. so you don't have to think about it, you're welcome ๐ซถ
๐ฅ NOTES ๐ฅ
sendfile() will transfer at most 0x7ffff000 (2,147,479,552) bytes, returning the number of bytes actually transferred. (This is true on both 32-bit and 64-bit systems.) same cap everywhere, no exceptions.
If you plan to use sendfile() for sending files to a TCP socket, but need to send some header data in front of the file contents, you will find it useful to employ the TCP_CORK option, described in tcp(7), to minimize the number of packets and to tune performance. chef's kiss optimisation ๐
Applications may wish to fall back to read(2) and write(2) in the case where sendfile() fails with EINVAL or ENOSYS. always have a plan B bestie.
If out_fd refers to a socket or pipe with zero-copy support, callers must ensure the transferred portions of the file referred to by in_fd remain unmodified until the reader on the other end of out_fd has consumed the transferred data. > โ ๏ธ do not touch that file mid-flight, i am begging you ๐ญ
The Linux-specific splice(2) call supports transferring data between arbitrary file descriptors provided one (or both) of them is a pipe. it's giving sendfile's cooler cousin ๐
๐ SEE ALSO ๐
copy_file_range(2), mmap(2), open(2), socket(2), splice(2)
and that's the whole page bestie, no cap ๐ฆ this was sendfile(2) from Linux man-pages 6.20, dated 2026-02-08. go forth and copy bytes inside the kernel, mwah ๐โจ
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-1-para
- Copyright 1998, Pawel Krawczyk
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms