0

I have learned that a signal can occur at any location when running one's code. For example, this code:

pid_t child;

void cleanup(int signal) {
 int status;
 while (waitpid((pid_t) (-1), 0, WNOHANG) > 0) {}
}

int main() {
   // Register signal handler BEFORE the child can finish
   signal(SIGCHLD, cleanup); // or better - sigaction
   child = fork();
   if (child == -1) { exit(EXIT_FAILURE);}

   if (child == 0) { /* I am the child!*/
     // Do background stuff e.g. call exec   
   } else { /* I'm the parent! */
      sleep(4); // so we can see the cleanup
      puts("Parent is done");
   }
   return 0;
}

I have also learned that you cannot do much inside a signal function handler besides affecting a sig_atomic_t variable. Is that true for waiting for a child-process as well? If so, what is the best way to handle a SIGCHLD?

Mister Tusk
  • 145
  • 1
  • 6
  • 2
    `waitpid` is a signal-safe function. And calling it in a `SIGCHLD` handler is quite natural and common. The problem is calling it in ohter signal handlers, as they should really be quick to avoid to avoid signal contention. – Some programmer dude Mar 15 '20 at 09:54
  • does that apply to ``wait`` as well? Why is it a signal-safe function? @Someprogrammerdude – Mister Tusk Mar 15 '20 at 11:53
  • [This signal concept POSIX reference](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04) could be helpful. As could [this Linux `signal-safety` manual page](http://man7.org/linux/man-pages/man7/signal-safety.7.html). – Some programmer dude Mar 15 '20 at 13:18
  • See [How to avoid using `printf()` in a signal handler?](https://stackoverflow.com/a/16891799/15168) which contains the list of POSIX functions that can be called from within a signal handler. Both `wait()` and `waitpid()` are in that list. Whether it is a good idea to do so is a separate discussion. If you've just received a SIGCHLD and you're using `waitpid()` with `WNOHANG` as shown, it is OK; you'll clean up all zombies (your process may have inherited some children that were run by whatever process executed your program (unlikely, but not impossible). – Jonathan Leffler Mar 15 '20 at 14:30

0 Answers0