Why does the following code execute the command:
"cat /etc/passwd | wc -l"
and not
"wc -l | cat /etc/passwd"?
Even though the debugging statements are in the order
b
a
int main() {
pid_t pid;
int fd[2];
int stdOut = dup(1);
pid = fork();
if (pid == 0) {
pipe(fd);
pid = fork();
if (pid == 0) {
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
write(stdOut, "a\n", 2);
execlp("cat", "cat", "/etc/passwd", NULL);
}
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
write(stdOut, "b\n", 2);
execlp("wc", "wc", "-l", NULL);
}
wait(NULL);
return 0;
}
The use of pipe
, dup2
and close
determines how the two processes are connected, not the order of execution. The process which runs first may block in a read
or write
access to the pipe until the other one sends or receives data respectively.
The execution order cannot be wrong because it is not specified. Any of parent or child may have to wait for something, and the scheduler does not guarantee fair distribution of resources. Maybe the creation of a child process takes some time, so the parent may reach
write(stdOut, "b\n", 2);
before the child reaches
write(stdOut, "a\n", 2);