I'm using sigaction(SIGTSTP, &ctrlz_signal, NULL);
to ensure I can catch Ctrl-Z
.
void ctrlz_signal(int sigNo) {
printf("Caught Ctrl-Z | curr_chld=%d\n", CURR_CHILD);
if(CURR_CHILD != 0) kill(CURR_CHILD, SIGTSTP);
}
CURR_CHILD
is set through forking:
sigaction(SIGTSTP, &ctrlz_signal, NULL);
int status;
CURR_CHILD = fork();
if (CURR_CHILD < 0) {
// ...
} else if (CURR_CHILD == 0) { // child
// exec(...)
} else { // back in parent
waitpid(CURR_CHILD, &status, 0); // wait for child to finish
// ...
}
It seems like it successfully stops the child process, but then it doesn't trigger the parent's waitpid
. I would've thought there would be a signal sent to the parent when I'd use this kill
function, but it seems like it isn't since my "shell" gets stuck on that waitpid
line.
How do I make it so that, once Ctrl-Z
is pressed, the process running an exec
command (which is a child, at that point) should be put in the background (stopped), and then the parent process should gain back its control over the flow of the program ?
The pid argument specifies a set of child processes for which status is requested. The waitpid() function only returns the status of a child process from the following set: If pid is equal to (pid_t)-1, status is requested for any child process. In this respect, waitpid() is then equivalent to wait().
The parent process sleeps for the specified number of seconds. When it wakes up, it sends its child process a SIGINT signal to kill it. If the child terminates before its parent finishes sleeping, the parent's SIGCHLD handler is executed, causing the parent to terminate immediately.
This flag specifies that waitpid should return immediately instead of waiting, if there is no child process ready to be noticed. WUNTRACED. This flag specifies that waitpid should report the status of any child processes that have been stopped as well as those that have terminated.
printf
is not an async-signal-safe function (as it is not re-entrant) and therefore must not be used in a signal handler. Using such functions will lead to undefined behavior.
If you want a child process that is not traced with ptrace
to return, you have to specify the WUNTRACED
option when you use waitpid
.
Alternatively, you can use ptrace
with the PTRACE_TRACEME
option, so that it will provide status for the child process even if the WUNTRACED
option is not specified in the waitpid
call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With