GNU Info

Info Node: (libc.info)Sigsuspend

(libc.info)Sigsuspend


Prev: Pause Problems Up: Waiting for a Signal
Enter node , (file) or (file)node

Using `sigsuspend'
------------------

   The clean and reliable way to wait for a signal to arrive is to
block it and then use `sigsuspend'.  By using `sigsuspend' in a loop,
you can wait for certain kinds of signals, while letting other kinds of
signals be handled by their handlers.

 - Function: int sigsuspend (const sigset_t *SET)
     This function replaces the process's signal mask with SET and then
     suspends the process until a signal is delivered whose action is
     either to terminate the process or invoke a signal handling
     function.  In other words, the program is effectively suspended
     until one of the signals that is not a member of SET arrives.

     If the process is woken up by delivery of a signal that invokes a
     handler function, and the handler function returns, then
     `sigsuspend' also returns.

     The mask remains SET only as long as `sigsuspend' is waiting.  The
     function `sigsuspend' always restores the previous signal mask
     when it returns.

     The return value and error conditions are the same as for `pause'.

   With `sigsuspend', you can replace the `pause' or `sleep' loop in
the previous section with something completely reliable:

     sigset_t mask, oldmask;
     
     ...
     
     /* Set up the mask of signals to temporarily block. */
     sigemptyset (&mask);
     sigaddset (&mask, SIGUSR1);
     
     ...
     
     /* Wait for a signal to arrive. */
     sigprocmask (SIG_BLOCK, &mask, &oldmask);
     while (!usr_interrupt)
       sigsuspend (&oldmask);
     sigprocmask (SIG_UNBLOCK, &mask, NULL);

   This last piece of code is a little tricky.  The key point to
remember here is that when `sigsuspend' returns, it resets the process's
signal mask to the original value, the value from before the call to
`sigsuspend'--in this case, the `SIGUSR1' signal is once again blocked.
The second call to `sigprocmask' is necessary to explicitly unblock
this signal.

   One other point: you may be wondering why the `while' loop is
necessary at all, since the program is apparently only waiting for one
`SIGUSR1' signal.  The answer is that the mask passed to `sigsuspend'
permits the process to be woken up by the delivery of other kinds of
signals, as well--for example, job control signals.  If the process is
woken up by a signal that doesn't set `usr_interrupt', it just suspends
itself again until the "right" kind of signal eventually arrives.

   This technique takes a few more lines of preparation, but that is
needed just once for each kind of wait criterion you want to use.  The
code that actually waits is just four lines.


automatically generated by info2www version 1.2.2.9