1 #ifndef lint 2 static char sccsid[] = "@(#)sleep.c 4.6 (Berkeley) 09/11/83"; 3 #endif 4 5 #include <sys/time.h> 6 #include <signal.h> 7 8 #define mask(s) (1<<((s)-1)) 9 #define setvec(vec, a) \ 10 vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 11 12 static int ringring; 13 14 sleep(n) 15 unsigned n; 16 { 17 int sleepx(), omask; 18 struct itimerval itv, oitv; 19 register struct itimerval *itp = &itv; 20 struct sigvec vec, ovec; 21 22 if (n == 0) 23 return; 24 timerclear(&itp->it_interval); 25 timerclear(&itp->it_value); 26 if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 27 return; 28 setvec(ovec, SIG_DFL); 29 omask = sigblock(0); 30 itp->it_value.tv_sec = n; 31 if (timerisset(&oitv.it_value)) { 32 if (timercmp(&oitv.it_value, &itp->it_value, >)) 33 oitv.it_value.tv_sec -= itp->it_value.tv_sec; 34 else { 35 itp->it_value = oitv.it_value; 36 /* 37 * This is a hack, but we must have time to 38 * return from the setitimer after the alarm 39 * or else it'll be restarted. And, anyway, 40 * sleep never did anything more than this before. 41 */ 42 oitv.it_value.tv_sec = 1; 43 oitv.it_value.tv_usec = 0; 44 } 45 } 46 setvec(vec, sleepx); 47 (void) sigvec(SIGALRM, &vec, &ovec); 48 ringring = 0; 49 (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 50 while (!ringring) 51 sigpause(omask &~ mask(SIGALRM)); 52 (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 53 (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 54 } 55 56 static 57 sleepx() 58 { 59 60 ringring = 1; 61 } 62