Descriptor tables, readiness I/O và signal-safe lifecycle
FD là handle per-process trỏ open file description/kernel object; socket, pipe, eventfd và files cùng chịu limits và close lifecycle.
FD & Signals
Descriptor semantics
open returns FD; dup/fork may share open file description including offset/status flags, while descriptor flags like close-on-exec are per FD. Closing one duplicate does not close object until last reference. Leaks occur across error paths, inheritance and long-lived registries.
Limits
RLIMIT_NOFILE per process, system file table, socket memory, inode/filesystem and cgroup constraints. EMFILE vs ENFILE indicate scopes. Raising limit without fixing leak merely delays outage and increases potential memory/resource blast.
Blocking/nonblocking/readiness
O_NONBLOCK returns EAGAIN when no progress; select/poll/epoll report readiness, not guarantee full operation. Edge-trigger requires drain-until-EAGAIN; level-trigger repeats while ready. Partial read/write, EINTR and close races need loops/protocol state.
Signals
Disposition process-wide, masks per-thread; delivery asynchronous except synchronous faults. Standard signals can coalesce, realtime queue. Handler only async-signal-safe operations; self-pipe/signalfd or atomic flag moves work into main loop.
Service shutdown
SIGTERM initiates stop intake/drain/close; SIGKILL gives no cleanup. SIGHUP often reload by convention; SIGCHLD prompts reap. Process supervisors send to main PID/group/cgroup depending model; verify child forwarding and deadlines.
Diagnostics
/proc/PID/fd, fdinfo, lsof, ss, slab/file-nr, limits and runtime pool metrics. Classify FD types/count growth and allocation stack when possible; avoid exposing symlink targets/paths containing secrets.