A good starting point is the article βA Small Path Through the Linux Kernelβ since 2001. The mechanisms are still similar, although the implementation has moved and is better studied in the newer kernel .
Inside the kernel, each open file descriptor corresponds to a struct file
that contains all the information about the open file or device. A file descriptor is really nothing more than an index in an FDT for a process. In the Linux kernel, the struct file
bound to the FDT function fd_install()
. struct file
can be reassigned to another dup2
file descriptor system call .
Processes can use the same FDT if the processes were created by the clone
system call with CLONE_FILES
, but there is no global FDT. A normal fork
operation creates a new FDT, which is a copy of the parent FDT. Practical use of this for each thread of a multi-threaded application is a cloned process sharing a common FDT, ensuring that all threads can use the same integer file descriptors. If you create a new process using fork
/ exec
, the new process starts with the same file descriptor, but can open and close files without affecting the parent.
FDT entries for stdin, stdout, stderr are inherited from the parent. There is nothing special about their implementation by the cores of these three FDT entries; their meaning comes from the usual use of the C library. Only the parent process decides what they are associated with. They can be connected to character devices, or they can be connected to files or pipes. For a character device, the most normal is a tty or pty device. The free book Linux Device Drivers provides a good overview of these.
source share