-
execvp not working right
I must be missing something here. I'm trying to use execvp to execute a command that a user passes to it. The way I'm doing this is by creating an arg_vector that stores the tokens of the command. Here's the code fragment:
Code:
char **arg_vector = NULL;
char *running = NULL;
char *token = NULL;
int i = 0;
int total_tokens = 0;
/* count_tokens returns the correct number of tokens delimited by whitespace */
total_tokens = count_tokens(command, DELIM);
arg_vector = (char **)malloc(sizeof(char **) *(total_tokens + 1));
if (arg_vector == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
running = strdupa(command);
/* fill up arg_vector with the tokens */
while ((token = strsep(&running, DELIM)) != NULL) {
arg_vector[i] = token;
i++;
}
arg_vector[total_tokens + 1] = NULL;
execvp(arg_vector[0], arg_vector);
If I pass the command as one of the following, they work just fine:
ls -l
ls -l /etc
ls /etc /bin
However, if I pass "ls -l /etc /bin" it fails. I'm not sure what it could be. Any hints would be much appreciated.
Thanks.
-
>>Any hints would be much appreciated.
What errors are produced?
If you're program is actually failing in something like execvp, use perror() to help find out why.
The args array should contain something like this:
Code:
my_args[0] = "/usr/bin/ls";
my_args[1] = "-l";
my_args[2] = "/etc";
my_args[3] = "/bin";
my_args[4] = NULL;
Maybe you should print your arg_vector array as part of a debug process to find out what your code is actually doing.
Check this FAQ for an example of execv:
http://faq.cprogramming.com/cgi-bin/...&id=1043284392 (opton 3)
-
arg_vector prints correctly. The error returned by perror is: perror: Bad address.
Am I initializing arg_vector correctly?
-
>> arg_vector = (char **)malloc(sizeof(char **) *(total_tokens + 1));
>> arg_vector[total_tokens + 1] = NULL;
If you allocate an array with 5 elements, the last valid index is 4.
gg
-
Awesome!!! It works!!! Many thanks!
-
> arg_vector = (char **)malloc(sizeof(char **) *(total_tokens + 1));
This is wrong TWICE
1. Don't cast the result of malloc - this is C, see the FAQ for why you shouldn't cast malloc in C.
2. the sizeof should be sizeof(char*). arg_vector is a char**, so it's a pointer to char* things, so you need to be using sizeof(char*). Think about what if you had int *ptr, would sizeof(int*) or sizeof(int) be the thing to use in the malloc call.
The generic malloc call is
p = malloc ( numRequired * sizeof(*p) );
which means you don't have to think back to what type you declared your pointer to be in the first place, and automatically adapts if you change the pointer type!