File & I/O · Section 2
write(2)
Write up to count bytes from buf to the file referenced by fd.
Signature
#include <unistd.h>
ssize_t write(int fd, const void * buf, size_t count);- fd
- File descriptor opened for writing (O_WRONLY or O_RDWR).
- buf
- Pointer to the data to write. The buffer is read-only from the kernel's perspective.
- count
- Number of bytes to attempt to write. The kernel caps this at 0x7ffff000 per call.
Description
write() writes up to count bytes from the buffer starting at buf to the file referred to by fd. The number of bytes actually written is returned; this may be less than count (a short write) if, for example, the underlying medium is slow, a signal interrupts the call, or count exceeds the kernel's per-call ceiling (currently 0x7ffff000). A return of -1 with errno set indicates failure. write() is one of the highest-frequency syscalls on any Linux system and underpins essentially every form of output: file I/O, sockets, pipes, terminals.
Architecture mapping
| Architecture | Number | ABI | Entry point |
|---|---|---|---|
| x86 (i386) | 4 | i386 | sys_write |
| x64 (x86_64) | 1 | common | sys_write |
| ARM64 (aarch64) | 64 | — | sys_write |
Kernel history
Introduced in Linux 1.0.
1.0
write() has been present in Linux since 1.0; behaviour is governed by POSIX.1 with small Linux-specific extensions around partial writes on pipes and the 0x7ffff000 ceiling.
seccomp & containers
Docker default profile
Allowed
Podman default profile
Allowed
write() is on the Docker and Podman default allow-lists. Blocking it is essentially impossible — without write() the process cannot even produce stderr output. If you need to constrain I/O, restrict by file descriptor in user space (e.g. with Landlock or a small wrapper) rather than via seccomp.
libseccomp
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);strace example
$ strace -e write echo hello
write(1, "hello\n", 6) = 6
+++ exited with 0 +++strace truncates large buffers by default; pass -s 4096 to see more. Pipe (|) writes can be matched with -e trace=write -P /dev/stdout to focus on a single fd.
Security & observability
write() is the canonical exfiltration syscall: any data leaving the process — to a socket, a pipe, a file, or /dev/tcp — flows through it. eBPF tracepoint sys_enter_write fires for every call; high-volume monitoring should sample or filter by fd category to avoid drowning. Rootkits sometimes hook write() to suppress log lines that mention their own files or processes (a 'log-grepper' filter); detection is straightforward if you also capture writes at the kernel layer via lsm/file_permission.
Errors
- EBADF
- fd is not a valid descriptor or is not open for writing.
- EFAULT
- buf is outside the process's accessible address space.
- EFBIG
- —
- EINTR
- The call was interrupted by a signal before any data was written.
- EINVAL
- —
- EIO
- —
- ENOSPC
- The device containing the file referenced by fd has no room for the data.
- EPIPE
- fd refers to a pipe or socket whose reading end is closed. SIGPIPE is also delivered (unless blocked or ignored).