Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `kill` to trigger a parent's `waitpid`

Tags:

c

shell

posix

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 ?

like image 851
payne Avatar asked Feb 06 '19 02:02

payne


People also ask

What are the arguments for Waitpid?

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().

Does SIGINT kill child processes?

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.

What is Wuntraced?

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.


1 Answers

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.

like image 92
P.W Avatar answered Oct 10 '22 21:10

P.W