File Descriptor
In short
A file descriptor is a small integer that a Unix-like operating system gives a process to refer to an open file, socket, pipe, or other input/output resource.
What is a file descriptor?
When a process opens a file on a Unix-like system, the kernel returns a small non-negative integer called a file descriptor. The process then passes that number to later system calls such as read, write, and close. The same mechanism covers much more than regular files: pipes, network sockets, terminals, and devices are all accessed through file descriptors, in line with the Unix idea that everything is a file.
Each process has a file descriptor table inside the kernel, and the descriptor is an index into it. By convention, 0 is standard input, 1 is standard output, and 2 is standard error, and each new open gets the lowest free number. Child processes inherit their parent's descriptors, which is how shell redirection and pipes work: 2>&1 means make descriptor 2 point wherever descriptor 1 points. Each process also has a limit on open descriptors, often 1,024 by default, so busy servers raise it, and code that forgets to close files eventually fails with a Too many open files error.
A file descriptor is like a coat-check ticket. You hand over your coat, the kernel opens the file, and you get back a numbered ticket; whenever you want to use the coat, you show the ticket. The number means nothing outside your own process, just as your ticket is useless at a different venue.
A file descriptor is often confused with a file name. A path names a file on disk, while a descriptor refers to one open instance of it inside one process, so two processes that open the same file get separate descriptors that may even have the same number. Windows uses a similar concept called a handle. In C, a FILE* stream from the standard library is a buffered wrapper around a file descriptor, and a socket is one kind of resource that a descriptor can point to.
Key takeaways
- A file descriptor is a per-process integer that refers to an open I/O resource.
- Descriptors 0, 1, and 2 are standard input, standard output, and standard error.
- Files, pipes, sockets, and devices are all accessed through descriptors.
- Shell redirection and pipes work by rearranging descriptors.
- Forgetting to close descriptors leads to Too many open files errors.
Example
# 0 = stdin, 1 = stdout, 2 = stderr
# Send normal output to one file and errors to another
ls /etc /missing > out.txt 2> errors.txt
# Point stderr (2) at stdout (1), then pipe both into grep
ls /etc /missing 2>&1 | grep missing
# List the open file descriptors of the current shell (Linux)
ls -l /proc/$$/fd
# Show the limit on open descriptors per process
ulimit -nReaders ask
What are file descriptors 0, 1, and 2?
They are the three standard streams every process starts with: 0 is standard input (stdin), 1 is standard output (stdout), and 2 is standard error (stderr).
What does Too many open files mean?
It means the process has reached its limit on open file descriptors. Either the program is leaking descriptors by not closing files or sockets, or it legitimately needs more and the limit should be raised with ulimit or the service configuration.
What does 2>&1 mean in a shell command?
It redirects file descriptor 2, standard error, to wherever descriptor 1, standard output, currently points. This lets you capture or pipe error messages together with normal output.
See also
- File SystemOperating Systems, p. 12A file system is the part of an operating system that organizes data on a storage device into files and folders and tracks where each piece is stored.
- System CallOperating Systems, p. 31A system call is a request from a program to the operating system kernel to perform a privileged action, such as reading a file or starting a process.
- ProcessOperating Systems, p. 23A process is a running instance of a program, with its own memory space, resources, and at least one thread of execution managed by the operating system.
- SocketNetworking, p. 27A socket is a software endpoint that a program opens to send and receive data over a network, identified by an IP address, a port number, and a protocol.
- ShellOperating Systems, p. 27A shell is a program that reads commands typed by a user or written in a script and asks the operating system to run them, usually through a text interface.
- Memory LeakOperating Systems, p. 19A memory leak is a bug where a program keeps holding memory it no longer needs, so its memory usage grows over time and can slow down or crash the system.
Spotted a mistake or something missing on this page?Suggest an edit