Assuming that argv[1]
is a single word command (like ls
) and argv[2]
is a second single word command (like more
), then:
Parent
- Create a pipe.
- Fork first child.
- Fork second child.
- Close both ends of the pipe.
- Parent waits for both children to die, reports their exit status, and exits itself.
Child 1
- Duplicates write end of pipe to standard output.
- Close both ends of the pipe.
- Uses
execvp()
to run the command inargv[1]
. - Exits, probably with an error message written to standard error (if the
execvp()
returns).
Child 2
- Duplicates read end of pipe to standard input.
- Close both ends of the pipe.
- Uses
execvp()
to run the command inargv[2]
. - Exits, probably with an error message written to standard error (if the
execvp()
returns).
The only remaining trick is that you need to create a vector such as:
char cmd1[2] = { argv[1], 0 };
char cmd2[2] = { argv[2], 0 };
to pass as the second argument to execvp()
.
Note that this outline does not break the strings up. If you want to handle an invocation such as:
./execute "ls -la" "wc -wl"
then you will need to split each argument into separate words and create bigger arrays for cmd1
and cmd2
. If you want to handle more than two commands, you need to think quite carefully about how you're going to manage the extra stages in the pipeline. The first and last commands are different from those in the middle (so 3 processes has three different mechanisms, but 4 or more substantially uses the same mechanism over and over for all except the first and last commands).