dup2(2)
System call
Makes one file descriptor a copy of another. It is the call that redirects standard output to a file or a pipe before an exec.
#include <unistd.h>
int dup2(int oldfd, int newfd);Description
dup2(oldfd, newfd) makes the descriptor newfd refer to the same open file as oldfd. If newfd was already open, it is closed first, without reporting any error. After the call, both numbers refer to the same file and share its offset and its file status flags; only the close-on-exec flag stays separate for each one.
The most common use is redirection. Descriptors 0, 1 and 2 are standard input, standard output and standard error (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO). dup2(fd, STDOUT_FILENO) sends everything the process writes to its standard output into fd, which can be a file or the write end of a pipe. Since descriptors survive execvp, a program started afterwards also writes to the new place, without knowing it.
Return value
The new descriptor, so newfd. -1 on error, with errno: EBADF if oldfd is not open (in that case newfd is not closed), EINTR if a signal interrupted the call. If oldfd and newfd are equal, dup2 does nothing and returns newfd.
Pitfalls
After
dup2(fd, STDOUT_FILENO), closefd: you no longer need it, and a pipe descriptor left open keeps the reader from ever seeing the end of the stream.The argument order is the one
cpuses: source first, destination second.dup2(STDOUT_FILENO, fd)does the opposite of what you meant.Redirection does not touch the
printfbuffer. Text written beforedup2and not flushed yet will go to the new place. Callfflush(stdout)before you redirect.
Example
#include <fcntl.h>#include <stdio.h>#include <unistd.h>
int main(void){ printf("on the screen\n"); fflush(stdout);
int fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { perror("open"); return 1; } dup2(fd, STDOUT_FILENO); close(fd); printf("in the file\n"); return 0;}$ gcc -Wall -Wextra redirect.c -o redirect$ ./redirecton the screen$ cat output.txtin the fileThe second printf is no different from the first: descriptor 1 now leads to the file.
process_stream_open
Write process_stream_open, which runs a command in a child and redirects its standard output or input to a pipe whose other end you return.