<aside> ๐งญ
Module 03 ยท File descriptors, inodes and filesystems
In Module 02 you watched a shell open a file and turn it into "output number 1", and then ls wrote to it without ever knowing. This module explains what those numbers are, what a file really is underneath, and why a disk can be full with plenty of space left.
๐ง concept โ ๐งฉ real-world analogy โ ๐งช exercise โ โ expected result (hidden) โ ๐ฏ interview questions (hidden)
</aside>
<aside> โ
Before you start, you should already know:
From Module 01 โ what a system call is, how to read strace output, what errno means, and how to read files under /proc.
From Module 02 โ what a process is, fork and exec, and that a child keeps its parent's open files.
If any of that is fuzzy, go back first. This module builds straight on top of it.
</aside>
<aside> ๐
Official docs: open(2) ยท proc(5) โ /proc/PID/fd ยท intro(2)
</aside>
When a program opens a file, it does not get the file back. It gets a small number.
That number is a file descriptor. It is nothing more than a position in a list the kernel keeps for your process. Entry 0, entry 1, entry 2, and so on.
So when your program says "write these bytes to 3", the kernel looks up entry 3 in your list and finds out what 3 actually means.
| What you think you have | What you actually have |
|---|---|
| "My program has the file open" | Your program has a number. The kernel has the file. |
| "File descriptor 3 is my log file" | Entry 3 in your process's list points to your log file. In another process, 3 means something completely different. |
Two consequences follow, and both matter later:
open returns 3, not 6. Close a descriptor and the next open reuses that number.<aside> ๐งฉ
Real-world analogy โ the cloakroom ticket
You hand your coat in at a cloakroom and get a ticket with a number on it.
You do not have your coat. You have a number. The cloakroom has your coat.
The ticket does not describe the coat. It does not say what colour it is or where it is hanging. It is just a number that the cloakroom staff can look up in their list.
And the number only means something in that cloakroom. Ticket 42 at the theatre and ticket 42 at the museum are not related in any way. That is exactly why descriptor 3 in one process has nothing to do with descriptor 3 in another.
Where the analogy stops working โ and it is the whole of Section B4. In a real cloakroom, if the coat is removed, your ticket becomes worthless.
In Linux the opposite happens. Someone can delete the file completely, and your ticket still works. The file stays alive, and keeps taking up disk space, for as long as anyone is still holding a ticket for it. That single difference causes one of the most common production incidents there is.
</aside>
๐งช Exercise A1.1 โ Look at your own list of open files
# Your shell's file descriptor list. Each entry is a numbered link.
ls -l /proc/$$/fd
# Open a file as descriptor 3 and look again
exec 3> /tmp/demo.txt
ls -l /proc/$$/fd
# Close it, and watch entry 3 disappear
exec 3>&-
ls -l /proc/$$/fd