SIGCHLD missed epoll_wait?

I wanted to understand the behavior of signals on fork. I wrote a small program to catch SIGCHLD using epoll_wait, but when I do "kill -9" on a forked child, I get no signal and the child is in a non-return state (I have a handler that executes wait ()).

Here is the code.

//....
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
pthread_sigmask(SIG_BLOCK, &mask, NULL);

signal_fd = signalfd(-1, &mask, 0);

memset(&tev, 0, sizeof(tev));
tev.events = EPOLLIN | EPOLLONESHOT;
tev.data.fd = signal_fd;

epoll_ctl(efd_, EPOLL_CTL_MOD, signal_fd, &tev);

while (1) {
    child_pid_ = fork();

    if (child_pid_ == 0) {
        close(signal_fd);
        close(efd_);
        make_grand_child(); //just sleeps in while(1) and never returns.
    } else {
        memset(&event, 0, sizeof(event));
        while (1) {
            epoll_wait(efd_, &event, 1, -1);
            deliver_events = (event.events & EPOLLERR|EPOLLHUP|EPOLLIN|EPOLLONESHOT);
            if (deliver_events) {
                parent_sig_handler(SIGCHLD);
                break;
            }
        }
    }
}

      

UPDATE:

Used by EPOLL_CTL_MOD without first adding (EPOLL_CTL_ADD). After I changed this, it worked like a charm.

0


source to share


1 answer


The default SIGCHLD disclaimer is ignored. Blocking the signal will not change the location, which it just makes it signalfd

possible to process it synchronously.



Add a signal handler for SIGCHLD using signal

or sigaction

. It doesn't have to do anything as it won't get executed. Since SIGCHLD is blocked, signalfd

will consume and process it before the handler.

0


source







All Articles