Nb-2.0
Nb-2.0

Reputation: 33

Determine the outcome of process ran via fork()/execl()

I have this code

# include <stdio.h> 
# include <unistd.h> 
# include <sys/wait.h> 
# include <stdlib.h> 
# include <string.h> 
# include <assert.h>

int parse( char * arg)
{ 
    int t; 
    t = fork(); 
    if (t < 0)
        return -1; 
    if (t == 0)
    {
        execl("/bin/sh", "sh", "-c", arg,NULL); 
        exit(1);
    } 
    return t; 
} 

int main(int argc, char *argv[])
{
    int t, tt, status, i;
    i = 1;

    for (i=1; i < argc; i++)
    {
        t = parse(argv[i]); 
        tt = wait(&status); 
        assert(tt == t);

    }
    return 0; 
}

that can run one or multiple commands.

I'm trying to make it stop if one of the given command failed.

Actually it keeps running even if one command failed

./test 'ech foo' 'echo too'
sh: 1: ech: not found
too

I did try multiple solutions with wait() and waitpid() but still not working.

Upvotes: 2

Views: 53

Answers (1)

dhke
dhke

Reputation: 15388

The exit status of the child process will be non-zero when the shell fails to execute a program. You can check by evaluating the status variable returned from the wait() call.

It's not so straightforward, since wait() packs more information into status than just the exit code. Additionally, the available information also changes depending on the value of WIFCONTINUED, WIFEXITED, ....

If we are interested in the fact that the child has exited successfully via the normal path, we could use:

int
main(int argc, char *argv[])
{
    int t, tt, status, i;
    i = 1;

    for (i=1; i < argc; i++)
    {
        t = parse(argv[i]); 
        tt = wait(&status);
        assert(tt == t);
        if ((! WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
            fprintf(stderr, "Command '%s' failed, aborting...", argv[i]));
            return 1;
        }

    }
    return 0; 
}

Upvotes: 4

Related Questions