Jordan
Jordan

Reputation: 2140

Changing from system() to execvp() in C shell program

I am working on writing a simple shell in C. A user inputs commands and they are stored in a two dimensional array, for example:

SHELL$ ls ; date ; ls
// This is parsed into the following
char* commands[1000] = {"ls", "date", "ls"};

I have a for loop that passes each element of the array to system if throughout my program I don't have a specific role for that input -- I do not have specific roles for ls and date:

if (did_not_process == 0)
    system(commands[i]);

Now I want to convert system() to execvp() and have the EXACT same functionality. This was my approach that did not function appropriately:

if (did_not_process == 0) {        
    command[0] = commands[i];
    command[1] = NULL;

    if (fork() == 0) {
        execvp(command[0], command);
    } else {
        wait(NULL); //wait for child to complete?
    }
}

Only problem is as I go through further iterations of the shell (a simple while loop) it prints executions sporadically and uncontrollably. The problem lies somewhere in the code I have shown, but I cannot figure out where.

Here is example output:

SHELL$ ls;date;ls
file
Mon Jul 16 13:42:13 EDT 2012
file
SHELL$ ls
SHELL$ file

Works the first time and then prints file on the same line as the shell input.

Upvotes: 2

Views: 1147

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126243

Just on general principles, you should be checking the return values of your system calls for errors:

int cpid = fork()
if (cpid == -1) {
    perror("fork");
} else if (cpid == 0) {
    execvp(command[0], command);
    perror("execvp");
    _exit(1);
} else {
    if (waitpid(cpid, 0, 0) < 0)
        perror("waitpid");
}

Upvotes: 3

Related Questions