UNIX pipes between child processes

I am trying to write a program that spawns an arbitrary number of child processes and a pipe between them, like a command line pipeline. In my case, I try to make "ls -l | more" and print it to stdout, and then the parent continues to execute more commands.

As a minimal example, I have the following code:

int main (int argc, const char * argv[]) { int fd[2]; pipe(fd); chdir("/directory/with/lots/of/files"); // Create one child process for more int pid = fork(); if (pid == 0) { close(fd[1]); int ret = dup2(fd[0],0); if (ret < 0) perror("dup2"); char *argv[10]; argv[0] = "more"; argv[1] = NULL; execvp("more", argv); } // Create another child process for ls int pid2 = fork(); if (pid2 == 0) { int ret = dup2(fd[1],1); if (ret < 0) perror("dup2"); char *argv[10]; argv[0] = "ls"; argv[1] = "-l"; argv[2] = NULL; execvp("ls", argv); } // wait for the more process to finish int status; waitpid(pid, &status, 0); printf("Done!\n"); return 0; } 

Now, when I run the program (enclosed in the main () function, of course), what I get is more, as expected. I press "d" to go to a longer output, and "u" up, and it seems to work fine. But when I reach the bottom, instead of exiting, like everyone else, it just leaves an empty line. Ctrl-C works to exit it, but exits the entire program, which means "Finish!". the line is never printed. A movie is available here that illustrates what happens (note that at the very end I press Ctrl-C to return to bash).

Any thoughts on this? I'm just trying to figure out how to change it to where instead of going to an empty line after it reaches the bottom more, it leaves more and returns to the parent process to continue execution.

+7
source share
2 answers

You need close() at least the end of your channel recording, otherwise more will never see EOF. For example:

  ... // close parent pipes close(fd[0]); close(fd[1]); // wait for the more process to finish int status; waitpid(pid, &status, 0); printf("Done!\n"); return 0; } 
+9
source

I think this is because of the wait() function . Following the logic, your second child process outputs to the first child process, that is, it should end first than the second.

In your wait function, you are expecting the completion of the first process, but you are not expecting a second process. This means that if the second process does not send EOF to the exit, your first process will not end, I think.

You can try to wait for the second process instead of the first and find out if this is a problem.

-one
source

All Articles