Execv, wait, Unix programming, How to wait for a baby

Hi I am working on a unix shell and I am having two problems. I was wondering if any of you can help me. My first problem is that the shell is not waiting for the child process to finish. In fact, I can type more commands while the child process is running. My problems arise in the next two lines. I am 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 way to execute a process entered by a 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");
    }
}

      

Here I am calling execute command. It works fine and starts the process, but it didn't wait for it to complete.

 execute(commandArgv, "STANDARD",0);

      

Do you guys know what I might be doing wrong? Thank you, I really appreciate any time you take to help me with this.

+2


source to share


3 answers


Once execvp () is run, it will never return. It replaces the in-memory executable application with the one supplied. So your fprintf () and wait () are in the wrong place.



+4


source


Apart from designing the correct logic correctly (Stéphane suggests everything is good), you can also fflush (stderr) after fprintf-ing to ensure that your error messages are fetched right away and not buffered.



+1


source


You have a small error in the process. There is no return after calling execvp. fork () gives you the parent and identical child, but execvp rewrites the child image as the command you invoke.

The execvp function only returns on severe errors that prevent the image from being overwritten. Therefore, you need to print things out before calling it. Therefore, you can also change EXIT_SUCCESS to EXIT_FAILURE .

Now there is another mistake using wait : you always want the parent to be expecting the child, not the other way around. You cannot ask the child to wait. She has nothing to wait, she will run and end. Thus, 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 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 really don't want the parent to wait. If so, just don't use the wait () function .

Take care, Beko

Edited: some minor bugs. pid for child - getpid ()

+1


source







All Articles