sigsuspend() with SIGINT and SIGCHLD

133 views Asked by At

I am studying this piece of code from the CSAPP book:

#include "csapp.h"

volatile sig_atomic_t pid;

void sigchld_handler(int s)
{
    int olderrno = errno;
    pid = Waitpid(-1, NULL, 0);
    errno = olderrno;
}

void sigint_handler(int s)
{
}

#define N 10
int main(int argc, char **argv) 
{
    sigset_t mask, prev;
    int n = N; /* 10 */
    Signal(SIGCHLD, sigchld_handler);
    Signal(SIGINT, sigint_handler);
    Sigemptyset(&mask);
    Sigaddset(&mask, SIGCHLD);

    while (n--) {
        Sigprocmask(SIG_BLOCK, &mask, &prev); /* Block SIGCHLD */
        if (Fork() == 0) /* Child */
            exit(0);

        /* Wait for SIGCHLD to be received */
        pid = 0;
        while (!pid) 
            Sigsuspend(&prev);

        /* Optionally unblock SIGCHLD */
        Sigprocmask(SIG_SETMASK, &prev, NULL); 

        /* Do some work after receiving SIGCHLD */
        printf(".");
    }
    printf("\n");
    exit(0);
}

While I understand a large part of it such as how sigsuspend uses mask and interacts with SIGCHLD, I don't understand this piece from the book If the parent caught a SIGINT, then the loop test succeeds and the next iteration calls sigsuspend again. If the parent caught a SIGCHLD, then the loop test fails and we exit the loop. At this point, SIGCHLD is blocked, and so we can optionally unblock SIGCHLD.

How does SIGINT interact with sigsuspend()? How will loop test succeed if SIGINT gets caught by parent? I guess the behavior of SIGINT is overwritten by the call to Signal(), which gets overwritten to doing nothing?

Also, how is SIGCHLD still blocked after loop test fails(by sigchld_handler())?

Much thanks in advance!

Other than this, can someone please do a walkthrough of this whole example? I don't have a solid understanding after reading it multiple times.

0

There are 0 answers