Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

374 Signals Chapter 10


sleep(unsigned int seconds)
{
struct sigaction newact, oldact;
sigset_t newmask, oldmask, suspmask;
unsigned int unslept;
/* set our handler, save previous information */
newact.sa_handler = sig_alrm;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGALRM, &newact, &oldact);
/* block SIGALRM and save current signal mask */
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
alarm(seconds);
suspmask = oldmask;
/* make sure SIGALRM isn’t blocked */
sigdelset(&suspmask, SIGALRM);
/* wait for any signal to be caught */
sigsuspend(&suspmask);
/* some signal has been caught, SIGALRM is now blocked */
unslept = alarm(0);
/* reset previous action */
sigaction(SIGALRM, &oldact, NULL);
/* reset signal mask, which unblocks SIGALRM */
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return(unslept);
}

Figure 10.29Reliable implementation ofsleep

It takes morecode to write this reliable implementation than what is shown in
Figure10.7. Wedon’t use any form of nonlocal branching (as we did in Figure10.8 to
avoid the race condition betweenalarmandpause), so there is no effect on other
signal handlers that may be executing when theSIGALRMis handled.

The nanosleep function is similar to the sleep function, but provides
nanosecond-level granularity.
#include <time.h>
int nanosleep(const struct timespec *reqtp,struct timespec *remtp);
Returns: 0 if slept for requested time or−1 on error
This function suspends the calling process until either the requested time has elapsed or
the function is interrupted by a signal. Thereqtpparameter specifies the amount of time
Free download pdf