4

I create a sigset_t and set it empty, then add SIGCHLD to it, then set it BLOCK:

sigset_t    sigmask;
sigemptyset (&sigmask);

sigprocmask (SIG_BLOCK, &sigmask, NULL);

Then create a signalfd via signalfd4()

int signalfd = signalfd4 (-1, &sigmask, sizeof(sigset_t), SFD_NONBLOCK);

Then add it to a epollfd which created previously:

struct epoll_event      epev;
memset (&epev, 0, sizeof(struct epoll_event));
epev.events        = POLLIN;

int retval = epoll_ctl (epollfd, EPOLL_CTL_ADD, signalfd, &epev);

and retval is 0;

At last, I use epoll_wait(epollfd, ...) to wait my child process which careate by fork() and sleep 2 senconds without do anything then exit, but nothing returned.

Anyone please give me some help on this? Thank you!

Kijewski
  • 25,517
  • 12
  • 101
  • 143
ScorpioCPH
  • 151
  • 2
  • 8

1 Answers1

1

After setting up the signal and the signal fd I found the following worked:

  epev.fd = sigfd;   // sigfd if from signalfd, need to remember it
  pid_t me = getpid();                                                                                             
  fork();                                                                                                                       

For the parent:

  if ( me == getpid() ) {                                                                                                       
    // parent                                                                                                                   
    while ( 1 ) { // loop of epoll_wait
      retval = epoll_wait ( epollfd, &epev, 1, -1 );

If this is the signal fd read it to find which signal was sent.

      if ( epev.data.fd == sigfd ) {
        struct signalfd_siginfo si;                                                                                             
        while ( 1 ) {                                                                                                           
          int nr = read ( sigfd, &si, sizeof si );                                                                              
          if ( nr != sizeof si ) {                                                                                              
            break;  // done reading from the signal fd
          }                                                                                                                     
          if ( si.ssi_signo == SIGCHLD ) {                                                                                      

do what the parent needs to do when it received SIGCHILD

          } else {

some other signal

          }                                                                                                                     
        }                                                                                                                       
      }                                                                                                                         
    }                                                                                                                           
  } else {                                                                                                                      
  // child    

child code

Martin Redmond
  • 13,366
  • 6
  • 36
  • 32
  • Thank you for your answer, by the way, my environment is `Android`, and I follow this [SIGCHLD not caught in epoll_wait](http://stackoverflow.com/questions/24153807/sigchld-not-caught-in-epoll-wait?rq=1), add a signal_handler to my sig, but epoll_wait return `EINTR`. – ScorpioCPH Sep 02 '14 at 13:29
  • regarding "do what the parent needs to do when it receives SIGCHLD". In particular is `wait()/waitpid()/waitid()` required? Seems you get the same info already in signalfd_siginfo so maybe not? – cheshirekow Aug 03 '18 at 23:04
  • I expect waitpid() is still needed, otherwise the child will not be reaped (= zombie). – Arnout Apr 29 '21 at 14:27