What is the behavior of blocking a signal?

430 Views Asked by At

If I send a bunch of SIGIO signals to a process and that process block SIGIO signals and doing something else. When I unblock the signal, will there be only one SIGIO signal or multiple SIGIO signals in sequence?

1

There are 1 best solutions below

1
On

The answer is ... it depends.

First the signal that is being sent is 'handled' by a handler method. There are two parts to a handler: top and bottom. The top should be quick, it should get the signal and set some flag and return. The bottom part will check that flag and then respond. Now some Linux/UNIX system reset the handler to the default when a signal happens (so you have to reset the sigaction for that signal in your handler).

Signals will queue up, but only a few (depending upon the implementation). If you are sending alog of signals you could loose all those that occur after the queue fills.

Look at signal and sigaction in man pages.

Here is an AIX/Linux solution. First setting the handler.

sigset_t  mask;
sigemptyset(&mask);

#ifdef AIX  
 exitaction.sa_handler = C_signalExit;
 exitaction.sa_mask    = mask;
 exitaction.sa_flags   = SA_OLDSTYLE; 
#else  // LINUX
 sigaddset(&mask, SIGHUP);
 sigaddset(&mask, SIGQUIT);
 sigaddset(&mask, SIGTERM);
 exitaction.sa_sigaction = C_signalActionExit;
 exitaction.sa_mask      = mask;
 exitaction.sa_flags     = SA_SIGINFO;
#endif

Now the handler code (top) - Note here I had to 'inject a workaround' to handle signals on Linux (but still keep the code compatible with AIX) SystemOS is the class that handles signals and other OS related activities.

#ifdef AIX
void C_signalExit(int signal) { sys->signalExit(signal,0,NULL); } 
void SystemOS::signalExit(int signal, int code, struct sigcontext *sigcon)
#else  // LINUX
void C_signalActionExit(int signal, siginfo_t* siginfo, void *data) 
{ sys->actionExit(signal,siginfo,data); }

void SystemOS::actionExit(int signal, siginfo_t* siginfo, void* data)
#endif
{ 
  switch(signal)
    {
    case  SIGINT   : // interrupt from keyboard (^C ??)
    case  SIGKILL  : // can't be caught or ignored // 080209 can't be blocked with sigblock() fields set si_pid,si_uid - see sigqueue(3)
    case  SIGTSTP  : // ^Z 
    case  SIGTTIN  : // background read
    case  SIGTTOU  : // background rite
 #ifdef AIX
    case  SIGDANGER: // disk space
    case  SIGPRE   : // program exception
    case  SIGSAK   : // secure attention
 #endif
    default :
      exec.kill(signal,SIGNAL_ERROR);   // exec is the 'main program' 
   }
} 

The exec.kill would be the bottom half - it takes the signal and value and will kill the application. You'd have some other function there (its not a standard method - but part of my app framework.

I hope this helps.