本文由 AI 分析生成
建立時間: 2026-01-19 來源: https://x.com/chessMan786/status/2013260660994421112
Summary
An introductory explainer on Unix/Linux file descriptors: the small integers returned by open() that act as per-process handles to files, devices, and sockets. It explains the per-process file descriptor table, the three default descriptors (stdin/stdout/stderr), and why this simple abstraction underpins redirection, pipes, and fork semantics. The piece is part 1 of a series and stays at the conceptual level with a small C demo.
一篇關於 Unix/Linux 檔案描述符的入門解說:open() 回傳的小整數,作為行程層級的檔案、裝置與 socket 句柄。文章說明了每個行程的檔案描述符表、三個預設描述符(stdin/stdout/stderr),以及為何這個簡單的抽象支撐了重導向、管道與 fork 語意。這是系列文的第一篇,以概念為主並附上一段 C 範例。
Prerequisites
- System calls (open/read/write/close) — file descriptors only make sense as the argument threaded through every I/O syscall.
- Process model — the descriptor table is per-process; understanding processes is needed to grasp inheritance and fork behavior.
- “Everything is a file” Unix philosophy — the design choice by Ritchie and Thompson that makes one integer handle apply to files, pipes, sockets, and devices alike.
Core Idea
A file descriptor is just a non-negative integer index into a per-process array (the file descriptor table) held in kernel memory. When you open() a file, the kernel sets up its internal bookkeeping and hands back the lowest unused index. Because every process starts with 0, 1, and 2 already bound to stdin, stdout, and stderr, the first file you open is typically descriptor 3. The kernel resolves any I/O syscall by looking up the integer in this table, which is why manipulating the table is how redirection and pipes are implemented.
Results
- Default descriptors: 0 = stdin, 1 = stdout, 2 = stderr, open before user code runs.
- First user-opened file is usually descriptor 3 (lowest free slot).
ulimit -non the author’s machine returns 1048575 (~2^20), the per-process descriptor cap.- Demo C program opens
test.txtwithO_RDONLY | O_CREAT, prints the descriptor, and closes it.
Limitations
- (Author-stated) This is part 1 and intentionally stops at the conceptual surface; the kernel structures behind the table (open file description, inode) are deferred to a later part.
- (Reading concern) Conflates the per-process table with the system-wide open file table; redirection and fork semantics actually hinge on the shared open file description, which the post only foreshadows.
- (Reading concern) The 2^20 limit is machine/config specific, not a universal Linux constant.
Reproducibility
- Code: available — full C snippet plus
gcc/run commands inline. - Datasets: n/a
- Compute: n/a — any Linux machine with a C compiler.
Insights
The “coat-check ticket” analogy is a clean intuition pump: the integer is meaningless on its own and only valuable as a lookup key the kernel honors. The real payoff flagged for later parts is that redirection, pipes, and fork quirks are all just table manipulation — a unifying mental model worth more than the trivia about specific numbers.
Connections
Raw Excerpt
File descriptors are integers, nothing more. But they’re integers with meaning. When you call open(), the kernel creates all sorts of internal bookkeeping structures to manage that file, then hands you back the simplest possible reference: a number.