Re: accomodating an unknown number of pipes in a shell program
- From: Logan Shaw <lshaw-usenet@xxxxxxxxxxxxx>
- Date: Thu, 12 Oct 2006 05:39:01 GMT
djneill@xxxxxxxxxxxxx wrote:
This is my first attempt to use pipes. My shell has to take in a
command line containing a number of commands separated by the '|'
character representing a pipe.
So /bin/ls | /bin/sort would list the files in the current working
directory in sorted order.
Each command is exec'd in a forked child process. The parent only
creates the pipes and waits for the children to finish.
Does this plan sound right?
1. Make exactly the number of pipes needed. Store as array of arrays
of 2 ints.
e.g. declare as int mypipes[num_commands-1][2]; // a pipe between each
command
2. Fork n processes.
3. Within each child process.
a. if this is the first command, direct stdout to the first pipe's
write end with dup2(pipes[0][1], 1). Close all existing pipe file
descriptors (and I mean all!): with close(pipe[i][0]) and close
(pipe[i][1]).
b. if this is the last command, direct stdin to the last pipe's
read end with dup2(pipes[LAST][0]). Close all pipe file descriptors:
as above.
c. else, for the commands in the middle with incoming and outgoing
pipes, direct stdin to the incoming pipe's read end, and stdout to the
outgoing pipe's write end. Close all pipe file descriptors: as above.
d. exec the appropriate command in the child process.
4. The parent process just closes all pipes' file descriptors and
waits for children to finish.
That plan should work.
However, you could also do it in a way that's a little bit like
recursion: take the last command, build a pipe, start the command
in a child, then recurse and pass the remainder (everything before
the last pipe character) on to another child to repeat the process.
When you finally have a command with no pipe character, just fork
and exec that command. (That's the base case.)
Either would work fine, but the recursive process makes things a
little cleaner. You don't need to dynamically allocate an array
of pipes because each time you fork, you are creating a new
context that only needs to hold one pipe. More importantly, you
can probably make each piece in the pipe wait on the piece that
is feeding it data. Then each process only needs to wait on one
other process, which makes the wait() logic much simpler.
- Logan
.
- References:
- Prev by Date: Re: Dynamic library cannot be loaded when run from gdb
- Next by Date: Re: mkfifo command usage to transfer info between 2 machines.
- Previous by thread: accomodating an unknown number of pipes in a shell program
- Next by thread: Re: accomodating an unknown number of pipes in a shell program
- Index(es):
Relevant Pages
|