Reputation: 1
I'm currently programming a shell which grabs input and stores it in a string (char*) array. To enable UNIX operations like pipelining, I want to be able to write commands like
echo this | function more | function2
To do this, I'm collecting the command and its arguments in a while loop, and try to copy all contents of the argument array into a new, 2-dimensional array which holds the entire command line, e.g. "ls -f -a
".
So far, this works, but then, I'm trying to reset the loop as soon as a "|
" was found in the command line, ignore the "|
", and begin a new loop doing the same thing until '\0'
is found, which marks the end of the original input:
char* arguments[MAXARGS]; // holds argument components, e.g. "ls" or "-f"
char** arg_collection[MAXARGS][MAXARGS]; // supposed to hold command lines, e.g. "ls -f -a"
argc_current = 0; // iterator for the loop, counts arguments
col_iterator = 0; // iterator for amount of command lines
int sentinel = 1; // sentinel value for while loop
...
while(sentinel)
{
arguments[argc_current] = (char*) malloc (sizeof(word)); // word is defined, just not listed on here - refers to the currently read command / argument
strcpy(arguments[argc_current], word); // copy current word into arguments
if(tokens[argc_current] == TOKEN_TERMINATOR || tokens[argc_curernt] == TOKEN_NULL)
{
sentinel = 0; // tokens holds information about the type of word, e.g. if it is '\0'
}
if(tokens[argc_current] == T_BAR) // if the word is "|"
{
for(i = 0; i < argc_current; i++)
{
strcpy(arg_collection[col_iterator][i], arguments[i]); // copy argument list into collection
}
col_iterator++; // increment command line counter
argc_current = 0; // reset argument counter, restart the loop
}
else
{
arg_current++; // increment current argument counter
}
}
evaluating arguments here..
The first loop works fine, e.g. if I type
echo this | echo more |
It fills arg_collection[0][0]
and arg_collection[0][1]
, so I get "echo this
" as a result.
After having incremented col_iterator
to 1, however, I hit a brick wall in form of a segmentation fault when calling strcpy upon noticing the second "|". Why?
Upvotes: 0
Views: 656
Reputation: 534
First you should allocate arg_collection before using it. (As you don't give the entire code, I assume you don't do it).
Then you are dereferencing two times your arg_collection on line:
strcpy(arg_collection[col_iterator][i], arguments[i]); // copy argument list into collection
When you must
strcpy(arg_collection[col_iterator], arguments[i]);
That is, you are treating the char at index i of string col_iterator in arg_collection as char *, when it is only a char.
Upvotes: 0
Reputation: 42185
It looks like word
is a char*
. If so, you should change
arguments[argc_current] = (char*) malloc (sizeof(word));
to
arguments[argc_current] = malloc(strlen(word)+1);
sizeof(word)
will give you the size of a pointer variable, not the size of the data it points to. strlen
tells you the number of characters in word
. The +1
is needed for the '\0'
terminator.
Upvotes: 2