<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>


๐Ÿ”ข Part A ยท File descriptors

A1 ยท What a file descriptor really is

<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:

<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

A2 ยท The three you always get: 0, 1 and 2