I wrote this program in order to use the execvp
command and this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, const char * argv[]) {
char **cmd;
int i;
if (argc == 1){
fprintf(stdout, "No command inserted!\n");
exit(EXIT_SUCCESS);
}
cmd = (char **) malloc( (argc + 1) * sizeof(char *));
cmd[0] = (char *) malloc( strlen(argv[1] + 1 ) * sizeof(char) );
strcpy(cmd[i], argv[i+1]);
if (argc > 2){
for (i = 1 ; i < argc - 1 ; i++ ){
cmd[i] = (char *) malloc( strlen(argv[i+1] + 1 ) * sizeof(char) );
strcpy(cmd[i], argv[i+1]);
}
cmd[argc] = NULL;
execvp(cmd[0], cmd);
fprintf(stderr, "Failed Execution or not existing command!!\n");
exit(EXIT_FAILURE);
}
cmd[1] = NULL;
execvp(cmd[0], cmd);
fprintf(stderr, "Failed Execution or not existing command!!\n");
exit(EXIT_FAILURE);
return 0;
}
I run this program on the terminal using these commands
./a.out ls
./a.out who
./a.out ls -l
./a.out mkdir newdir
The first two worked fine as well as the other commands without arguments. With the last two I get a No such File or Directory
error in the terminal, but actually the mkdir
command creates the directory newdir...
Can someone help me
you're setting
cmd[argc] = NULL;
but that's too much by 1 (argc
is the count of args with your command included). Socmd[argc - 1]
isn't initialized (note that the loop above stops atargc - 2
You need to set
cmd[argc - 1]
toNULL
instead or else another trash argument is passed toexecvp
, which explains for instance thatmkdir
works for the first argument, but fails when processing the garbage arg. All commands receive a garbage argument because of this shift.You need an array of pointers of size
argc
, notargc + 1
since thea.out
command isn't considered.Also, as noted in comments, you're using
i
not initialized at first, which work (since yourmkdir
command works) but out of luck (undefined behaviour)A much simpler way to do it would be to copy the array of
argv
pointers (ignoring the first one which is your comment) without duplicating the memory for the string contents (since you're not modifying them).