Each process has an "open file table." The table is an array of pointers to structures that describe an open file. (A file descriptor, a small integer, is an index into this table.) The structures keep track of both what file is being operated on and where in the file the next operation will take place -- if the process does a read and then another read, the second one starts where the first one left off. Open file 0 is stdin. Open file 1 is stdout. Open file 2 is stderr. A child process by default inherits a copy of its parent's open file table. This allows the parent to control the source of stdin, say, in the child: the parent arranges to open some data source using file descriptor 0 before it hands control to the child. The child code is obvlious to this redirection.