Results 1 to 2 of 2
Enjoy an ad free experience by logging in. Not a member yet? Register.
- Join Date
- Jan 2003
standard output and standard error
thanks in advance.
- Join Date
- Oct 2001
- Täby, Sweden
I'll start from the ground, then, since I don't know how much you know. In any given UNIX kernel (except for the Hurd), the most basic kind of out-side world communication (not just IPC) that a process has, is through a file descriptor. A file descriptor can be connected to a disk file, a device, a pipe, a socket, etc. A file descriptor is identified by a unique number, which on Linux can range from 0 to 1023. The basic operations that can be performed on a file descriptor is to read and write bytes. In the beginning, all file descriptors were stream based (block devices had special treatment before seek got a 32-bit parameter, but still).
The two most basic system calls for process management are fork() and exec(). fork() creates an exact clone of the running process, each running in their own memory space, and exec() replaces the running process with the process image stored in a file. For example, when you type "ls" in a shell, the shell forks, and then the child process execs /bin/ls. Although memory contents aren't preserved through an exec, file descriptors are, so if the original process had opened a terminal, the child process will also be able to use that terminal.
This is where standard input, output and error comes in. It has been standardized that processes shall read data from file descriptor 0, write data to fd 1, and print error fd 2. There they are called standard input, output and error. The stdio library (which is really just a bunch of wrapper functions over file descriptors) provides FILE * structures to each of these called stdin, stdout and stderr, if you're programming in C.
The strength of this is that "sort", for example, always reads data from its standard input (file descriptor 0), even though it has no idea of what is connected to it. It can be the user's terminal (a device), a disk file, or a pipe from another process. Also, it only writes to its standard output, which can also be the terminal, or a pipe to another process or anything.
So, for example, if you run "ls | sort -r" in the shell, the shell creates a pipe (which is two file descriptors, one for reading and one for writing, ie. one for each end of the pipe), then forks twice. The first child closes the read file descriptor of the pipe, puts the write one on file descriptor 1, and execs /bin/ls. The second one closes the write end of the pipe, puts the read end on file descriptor 0, and execs /usr/bin/sort.