Files & I/O

redirection and dup/dup2

/ dup -> dupe /

Picture three pipes coming out of a machine labelled 'input,' 'output,' and 'errors.' By default they run to the keyboard and the screen. Redirection is rerouting one of those pipes somewhere else - sending output into a file instead of the screen - without changing the machine itself. dup and dup2 are the plumbing tools that do the rerouting.

Concretely, redirection works because of the descriptor table. A program writes to standard output by writing to file descriptor 1; it does not know or care what fd 1 is connected to. So if you arrange for fd 1 to point at a file before the program runs, all its output silently lands in that file. dup(oldfd) makes a copy of a descriptor in the lowest free slot, both referring to the same open-file structure (so they share the offset). dup2(oldfd, newfd) is the precise version: it makes newfd refer to the same open file as oldfd, first closing newfd if it was open - this is the workhorse for redirection. The classic recipe: open the target file (say it lands on fd 5), then call dup2(5, 1) so that fd 1 now points at the file, then close(5); from now on every write to standard output goes to the file. A shell does exactly this between fork() and exec() to implement '> out.txt'.

Why it matters: this is the mechanism behind shell redirection (> and <) and the foundation of pipelines. The deep idea is the separation between what a program writes to (a fixed descriptor number) and where that descriptor leads (rearrangeable from outside). Because the program just uses fd 0, 1, 2, the surrounding shell or parent process can wire those to files, pipes, or other programs without the program ever knowing - which is exactly why Unix tools combine so freely.

/* make standard output go into out.txt, the way a shell does for '> out.txt' */ int fd = open("out.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); dup2(fd, 1); /* fd 1 (stdout) now points at out.txt */ close(fd); /* the extra descriptor is no longer needed */

After dup2(fd, 1), every printf and write to stdout lands in out.txt - the program never notices.

dup2(oldfd, newfd) closes newfd first if it was open, then makes it a copy - the two share one open-file description and thus one file offset, unlike two separate open() calls. Redirection works only because a program targets a descriptor number, not a fixed destination.

Also called
redirecting standard streamsduplicating a descriptor重導向標準串流