I have a function in C that creates a child process and uses execvp()
to execute a certain task.
pid_t pid = fork();
if (pid == 0) {
if (execvp(cmd->arg_array[0], cmd->arg_array) == -1) {
exit(-1);
return ERROR;
}
} else if (pid < 0)
return ERROR;
//Some more code...
return NO_ERROR;
As you can see, if the task fails, the process containing it should be deleted and the function returned with ERROR
value.
I tried implementing this functionality with an exit(-1)
(and _exit()
also), but the return statement is never reached, since the code is in the parent process zone. Also, if I remove the exit()
and let the function return the error, the process keeps existing and interferes with the program functioning. How can I kill the created child process before the function returns when execvp
task fails?
the process containing it should be deleted and the function returned with
ERROR
value.
No, that's not what happens. A successful fork()
creates a new process and returns 0
to this new process. In you example, execvp
is executed in this new process and if it fails, you immediately do exit(-1);
, at which point the process terminates and the line return ERROR;
will never be reached.
You can collect the child's exit status in the parent process by using wait
or waitpid
. Use WIFEXITED
/WEXITSTATUS
, WIFSIGNALED
/WTERMSIG
, WIFSTOPPED
/WSTOPSIG
and WIFCONTINUED
to unpack the information about how it exited (or stopped/continued).
Example:
pid_t pid = fork();
if (pid == 0) {
execvp(cmd->arg_array[0], cmd->arg_array);
// there's no need to check the return value from execvp:
// if execvp returns, it means that it failed.
_exit(1); // use _exit() instead of exit() to abort when exec fails
} else if (pid == -1)
return ERROR;
}
// parent
int wstatus;
pid_t child;
while( (child = wait(&wstatus)) != -1 ) {
printf("child %ld died with status %d\n", (long)child, wstatus);
}
Note: The function _exit()
is like exit()
, but does not call any functions registered with atexit()
or on_exit()
and you probably wouldn't want those to be called just because execvp
failed.
When a child process is created via fork()
, it inherits copies of its parent's on_exit
registrations. Upon a successful call to one of the exec()
functions (like execvp
), all registrations are removed.