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