Question

Hi I'm working on a unix shell and I'm running into two problems. I was wondering if any of you could help me out. My first problem is that the shell is not waiting for the child process to terminate. I can actually go type more commands while the child process is running. My second problems is in the following two lines. I'm not getting any display on the shell.

    fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
    fprintf(stderr, "Child pid = %d\n", pid);

I have the following method to execute a process entered by the user: i.e. firefox, ls -a, etc

void execute(char *command[], char *file, int descriptor){
    pid_t pid;
    pid = fork();

    if(pid == -1){
        printf("error in execute has occurred\n");
    }
    if(pid == 0){           
        execvp(*command,command);
        fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
        fprintf(stderr, "Child pid = %d\n", pid);
        wait(&status);
            exit(EXIT_SUCCESS);
    }
    else{
        printf("ignore for now\n");
    }
}

This is where I call the execute command. It works fine and launches a process, but it doesn't wait for it to finish.

 execute(commandArgv, "STANDARD",0);

Do you guys have any idea what I might be doing wrong? Thanks I really appreciate any time you take to help me on this.

Was it helpful?

Solution

Once execvp() runs, it will never return. It replaces in-memory the running app with whatever was provided. So your fprintf() and wait() are in the wrong place.

OTHER TIPS

Other than getting the actual logic worked out correctly (Stéphane's suggestions all good) you might also want to fflush(stderr) after fprintf-ing, to ensure your error messages make it out right away instead of being buffered.

You have a little error in how the process works. After execvp is called, there is no turning back. fork() gives you have the parent and an identical child, but execvp overwrite child image to be the command you are calling.

The execvp returns only when a severe errors occur that prevent overwriting the image. So, you need to print things before its call. So you also may want to change the EXIT_SUCCESS to an EXIT_FAILURE there.

Now there is another mistake using wait: you always want the parent waiting for the child, not the other way around. You cannot ask for the child to wait. She has nothing to wait, she will run and terminate. So, you need to move the wait() call to the else part.

void execute(char *command[], char *file, int descriptor)
{
    pid_t pid;
    pid = fork();

    if(pid == -1)
    {
        printf("fork() error in execute() has occurred\n");
        return; /* return here without running the next else statement*/
    }
    if(pid == 0)
    {           
        fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
        fprintf(stderr, "Child pid = %d\n", getpid());
        execvp(*command,command);
        fprintf(stderr, "Error! Can't overwrite child's image!\n");
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("Parent waiting for child pid: %d\n", pid);
        wait(&status);
        printf("Parent running again\n");
    }
}

But reading your question, maybe you actually don't want the parent to wait. If that is the case, just don't use the wait() function.

Take care, Beco

Edited: some minor mistakes. pid of child is getpid()

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