Reputation: 33
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
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