Question

I use this code to run some of shell commands, but it exits after ls command.: where is my wrong?

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

#define MAX_LINE 80 /* The maximum length command */

void setup(char inputBuffer[], char *args[],int *background)
{
    int length,  i, start, ct;    

    ct = 0;

    /* read what the user enters on the command line */
    length = read(STDIN_FILENO,inputBuffer,MAX_LINE);  
    start = -1;
    if (length == 0)
        exit(0);            /* ^d was entered, end of user command stream */

    if ( (length < 0) && (errno != EINTR) ) {
        perror("error reading the command");
    exit(-1);           /* terminate with error code of -1 */
    }

    printf(">>%s<<",inputBuffer);
    for (i=0;i<length;i++){ /* examine every character in the inputBuffer */

        switch (inputBuffer[i]){
        case ' ':
        case '\t' :               /* argument separators */
    if(start != -1){
                args[ct] = &inputBuffer[start];    /* set up pointer */
        ct++;
    }
            inputBuffer[i] = '\0'; /* add a null char; make a C string */
    start = -1;
    break;

            case '\n':                 /* should be the final char examined */
    if (start != -1){
                args[ct] = &inputBuffer[start];     
        ct++;
    }
            inputBuffer[i] = '\0';
            args[ct] = NULL; /* no more arguments to this command */
    break;

        default :             /* some other character */
    if (start == -1)
        start = i;
            if (inputBuffer[i] == '&'){
      *background  = 1;
              inputBuffer[i-1] = '\0';
    }
} /* end of switch */
 }    /* end of for */
 args[ct] = NULL; /* just in case the input line was > 80 */

for (i = 0; i <= ct; i++)
         printf("args %d = %s\n",i,args[i]);
} /* end of setup routine */

int main(void)
{
char inputBuffer[MAX_LINE]; /*buffer to hold command entered */
    int background; /* equals 1 if a command is followed by '&' */
    char *args[MAX_LINE/2 + 1]; /*command line arguments */
int should_run = 1; /* flag to determine when to exit program */
while (should_run) {
    //background=0;
    printf("Msh>");
    fflush(stdout);
    setup(inputBuffer, args, &background);
    execvp(args[0], args);
}
return 0;
}
Was it helpful?

Solution

As Kerrek SB already said, execvp does not return.

To add a little more info: the execv-family of functions replaces your process (running program) with another. This, in cooperation with fork is what happens inside a system() call.

To put it more bluntly:

If you want to run a system command from your C program, and carry on based on "return" value, you should use the system() call. See example.

If you want to spawn a child process, which should run another executable, you should fork, and inside the child process use execv. See the following example.

OTHER TIPS

Remember that execvp does not return.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top