1*13019Ssam /* @(#)sleep.c 4.3 (Berkeley) 06/12/83 */ 212977Ssam 31979Swnj #include <signal.h> 41979Swnj #include <setjmp.h> 512977Ssam #include <time.h> 61979Swnj 71979Swnj static jmp_buf jmp; 81979Swnj 912977Ssam #define mask(s) (1<<((s)-1)) 1012977Ssam #define setvec(vec, a) \ 1112977Ssam vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 1212977Ssam 131979Swnj sleep(n) 1412977Ssam unsigned n; 151979Swnj { 1612977Ssam int sleepx(), omask; 1712977Ssam struct itimerval itv, oitv; 1812977Ssam register struct itimerval *itp = &itv; 1912977Ssam struct sigvec vec, ovec; 201979Swnj 2112977Ssam if (n == 0) 221979Swnj return; 2312977Ssam timerclear(&itp->it_interval); 2412977Ssam timerclear(&itp->it_value); 2512977Ssam if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 2612977Ssam return; 2712977Ssam setvec(ovec, SIG_DFL); 281979Swnj if (setjmp(jmp)) { 2912977Ssam (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 3012977Ssam (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 311979Swnj return; 321979Swnj } 3312977Ssam omask = sigblock(0); 3412977Ssam itp->it_value.tv_sec = n; 3512977Ssam if (timerisset(&oitv.it_value)) { 3612977Ssam if (timercmp(&oitv.it_value, &itp->it_value, >)) 3712977Ssam oitv.it_value.tv_sec -= itp->it_value.tv_sec; 381979Swnj else { 3912977Ssam itp->it_value = oitv.it_value; 4012977Ssam /* 41*13019Ssam * This is a hack, but we must have time to 42*13019Ssam * return from the setitimer after the longjmp 43*13019Ssam * or else it'll be restarted. And, anyway, 44*13019Ssam * sleep never did anything more than this before. 4512977Ssam */ 46*13019Ssam oitv.it_value.tv_sec = 1; 47*13019Ssam oitv.it_value.tv_usec = 0; 481979Swnj } 491979Swnj } 5012977Ssam setvec(vec, sleepx); 5112977Ssam (void) sigvec(SIGALRM, &vec, &ovec); 5212977Ssam if (setitimer(ITIMER_REAL, itp, (struct itimerval *)0) < 0) 5312977Ssam longjmp(jmp, 1); 54*13019Ssam for (;;) 55*13019Ssam sigpause(omask &~ mask(SIGALRM)); 561979Swnj /*NOTREACHED*/ 571979Swnj } 581979Swnj 591979Swnj static 601979Swnj sleepx() 611979Swnj { 6212977Ssam 631979Swnj longjmp(jmp, 1); 641979Swnj } 65