1*13582Ssam #ifndef lint 2*13582Ssam static char sccsid[] = "@(#)sleep.c 4.4 (Berkeley) 07/01/83"; 3*13582Ssam #endif 412977Ssam 5*13582Ssam #include <sys/time.h> 61979Swnj #include <signal.h> 71979Swnj #include <setjmp.h> 81979Swnj 91979Swnj static jmp_buf jmp; 101979Swnj 1112977Ssam #define mask(s) (1<<((s)-1)) 1212977Ssam #define setvec(vec, a) \ 1312977Ssam vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 1412977Ssam 151979Swnj sleep(n) 1612977Ssam unsigned n; 171979Swnj { 1812977Ssam int sleepx(), omask; 1912977Ssam struct itimerval itv, oitv; 2012977Ssam register struct itimerval *itp = &itv; 2112977Ssam struct sigvec vec, ovec; 221979Swnj 2312977Ssam if (n == 0) 241979Swnj return; 2512977Ssam timerclear(&itp->it_interval); 2612977Ssam timerclear(&itp->it_value); 2712977Ssam if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 2812977Ssam return; 2912977Ssam setvec(ovec, SIG_DFL); 301979Swnj if (setjmp(jmp)) { 3112977Ssam (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 3212977Ssam (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 331979Swnj return; 341979Swnj } 3512977Ssam omask = sigblock(0); 3612977Ssam itp->it_value.tv_sec = n; 3712977Ssam if (timerisset(&oitv.it_value)) { 3812977Ssam if (timercmp(&oitv.it_value, &itp->it_value, >)) 3912977Ssam oitv.it_value.tv_sec -= itp->it_value.tv_sec; 401979Swnj else { 4112977Ssam itp->it_value = oitv.it_value; 4212977Ssam /* 4313019Ssam * This is a hack, but we must have time to 4413019Ssam * return from the setitimer after the longjmp 4513019Ssam * or else it'll be restarted. And, anyway, 4613019Ssam * sleep never did anything more than this before. 4712977Ssam */ 4813019Ssam oitv.it_value.tv_sec = 1; 4913019Ssam oitv.it_value.tv_usec = 0; 501979Swnj } 511979Swnj } 5212977Ssam setvec(vec, sleepx); 5312977Ssam (void) sigvec(SIGALRM, &vec, &ovec); 5412977Ssam if (setitimer(ITIMER_REAL, itp, (struct itimerval *)0) < 0) 5512977Ssam longjmp(jmp, 1); 5613019Ssam for (;;) 5713019Ssam sigpause(omask &~ mask(SIGALRM)); 581979Swnj /*NOTREACHED*/ 591979Swnj } 601979Swnj 611979Swnj static 621979Swnj sleepx() 631979Swnj { 6412977Ssam 651979Swnj longjmp(jmp, 1); 661979Swnj } 67