Reputation: 953
I'm trying to implement a simple shell program that supports multiple piping. For now my shell can implement some simple builtin commands and also external commands. I did this by getting the user input from the command line which is separated by space " "
and put each string in a char* argv[]
. The problem now is executing pipes. I read a litle bit about it in this link http://www.cs.loyola.edu/~jglenn/702/S2005/Examples/dup2.html. And I understood how it works.
So I thought about strcmp
each argv[i]
with "|"
and when I meet a pipe, I fork
a new process. I then put the strings before the pipe in a char* argv[]
and the one after the pipe in another char* argv[]
. This might work for 1 pipe but if the user entered multiple have multiple pipes, things might get tedious with this method. My main problem is about separating the strings at both ends of the pipes. Any ideas on how I can implement it? Thanks.
Upvotes: 1
Views: 1471
Reputation: 36049
Divide and conquer:
Step 3 is, due to C array semantics, pretty simple:
char **arguments;
int pipe_position = /* for example: */ 5;
assert( strcmp( arguments[pipe_position], "|" ) == 0 );
arguments[pipe_position] = NULL;
char **my_arguments = arguments;
arguments = arguments + pipe_position + 1;
and then my_arguments is an array of length pipe_position
containing the first arguments, and arguments
is an array of length argc - pipe_position - 1
containing the rest. You can give these pointers to execvp without a problem. Yes, they point to the same block of memory, but that's not execvp's concern.
Upvotes: 2
Reputation: 77454
You can probably even just reuse the argv array by replacing the pipes with a null string (which terminates the argv array).
So your array was something like this:
"a", "b", "|", "c", "d", "e", "|", "f", "g", "h", NULL
which you change into
"a", "b", NULL, "c", "d", "e", NULL, "f", "g", "h", NULL
and voila, here are your three command lines: argv
, argv+3
, argv+7
The difficult part with pipes is setting up the stdin and stdout file descriptors, not the actual execution of commands.
Upvotes: 2