Unix Piping using Fork and Dup
15,574
Your example code was syntactically and semantically broken (e.g. pipefd2 not decared, confusion between pipefd and pipefd2, etc.) Since this smells like homework, please make sure you understand my annotations below and ask more if you need to. I've omitted error checks on pipe, fork and dup, but they should be there, ideally.
int main(int argc, char *argv[]) {
int pipefd[2];
pid_t ls_pid, wc_pid;
pipe(pipefd);
// this child is generating output to the pipe
//
if ((ls_pid = fork()) == 0) {
// attach stdout to the left side of pipe
// and inherit stdin and stdout from parent
dup2(pipefd[1],STDOUT_FILENO);
close(pipefd[0]); // not using the right side
execl("/bin/ls", "ls","-al", NULL);
perror("exec ls failed");
exit(EXIT_FAILURE);
}
// this child is consuming input from the pipe
//
if ((wc_pid = fork()) == 0) {
// attach stdin to the right side of pipe
// and inherit stdout and stderr from parent
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[1]); // not using the left side
execl("/usr/bin/wc", "wc", NULL);
perror("exec wc failed");
exit(EXIT_FAILURE);
}
// explicitly not waiting for ls_pid here
// wc_pid isn't even my child, it belongs to ls_pid
return EXIT_SUCCESS;
}
Author by
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
Let's say within a program I want to execute two processes, one to execute a
ls -al
command, then piping the result into thewc
command, and displaying the output on the terminal. How can I do this using pipe file descriptors? So far the code I have written:int main(int argc, char* argv[]) { int pipefd[2]; int pipefd2[2]; pipe(pipefd2); if ((fork()) == 0) { dup2(pipefd2[1], STDOUT_FILENO); close(pipefd2[0]); close(pipefd2[1]); execl("ls", "ls", "-al", NULL); exit(EXIT_FAILURE); } if ((fork()) == 0){ dup2(pipefd2[0], STDIN_FILENO); close(pipefd2[0]); close(pipefd2[1]); execl("/usr/bin/wc", "wc", NULL); exit(EXIT_FAILURE); } close(pipefd[0]); close(pipefd[1]); close(pipefd2[0]); close(pipefd2[1]); }
An example would be greatly helpful.
-
caf about 14 yearsIt is not true that closing one
dup
'd file descriptor closes the other. Closing one just removes one handle to the open file. The file itself is not closed until alldup
'd file descriptors to it are closed. -
caf about 14 yearsOh, and you should close the
pipefd
file descriptors in the parent - it doesn't need them (and the reading child won't see end-of-file until the parent closes its handle on the writing end). Again,close()
only gets rid of the handle you pass it, the underlying pipe isn't closed until all of the handles to it, in every process, are closed. -
tmc about 11 yearsIs your last comment correct? Aren't they both children of one parent?
-
象嘉道 over 3 yearscan we get rid of
close
here?