You must call wait()
or waitpid()
in the parent process and it will give you the exit status of the program executed by execl()
. Not calling one of these will make the child process remain a zombie when it terminates, i.e. a process that is dead but stays in the process table because its parent wasn't interested in its return code.
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
...
pid_t pid;
int status;
if ((pid = fork()) == 0) {
/* the child process */
execl(..., NULL);
/* if execl() was successful, this won't be reached */
_exit(127);
}
if (pid > 0) {
/* the parent process calls waitpid() on the child */
if (waitpid(pid, &status, 0) > 0) {
if (WIFEXITED(status) && !WEXITSTATUS(status)) {
/* the program terminated normally and executed successfully */
} else if (WIFEXITED(status) && WEXITSTATUS(status)) {
if (WEXITSTATUS(status) == 127) {
/* execl() failed */
} else {
/* the program terminated normally, but returned a non-zero status */
switch (WEXITSTATUS(status)) {
/* handle each particular return code that the program can return */
}
}
} else {
/* the program didn't terminate normally */
}
} else {
/* waitpid() failed */
}
} else {
/* failed to fork() */
}
The _exit()
call in the child is to prevent it from continuing execution in case execl()
fails. Its return status (127) is also necessary to distinguish the case of an eventual execl()
failure in the parent.