1*12977Ssam /* @(#)sleep.c 4.2 (Berkeley) 06/10/83 */ 2*12977Ssam 31979Swnj #include <signal.h> 41979Swnj #include <setjmp.h> 5*12977Ssam #include <time.h> 61979Swnj 71979Swnj static jmp_buf jmp; 81979Swnj 9*12977Ssam #define mask(s) (1<<((s)-1)) 10*12977Ssam #define setvec(vec, a) \ 11*12977Ssam vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 12*12977Ssam 131979Swnj sleep(n) 14*12977Ssam unsigned n; 151979Swnj { 16*12977Ssam int sleepx(), omask; 17*12977Ssam struct itimerval itv, oitv; 18*12977Ssam register struct itimerval *itp = &itv; 19*12977Ssam struct sigvec vec, ovec; 201979Swnj 21*12977Ssam if (n == 0) 221979Swnj return; 23*12977Ssam timerclear(&itp->it_interval); 24*12977Ssam timerclear(&itp->it_value); 25*12977Ssam if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 26*12977Ssam return; 27*12977Ssam setvec(ovec, SIG_DFL); 281979Swnj if (setjmp(jmp)) { 29*12977Ssam (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 30*12977Ssam (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 311979Swnj return; 321979Swnj } 33*12977Ssam omask = sigblock(0); 34*12977Ssam itp->it_value.tv_sec = n; 35*12977Ssam if (timerisset(&oitv.it_value)) { 36*12977Ssam if (timercmp(&oitv.it_value, &itp->it_value, >)) 37*12977Ssam oitv.it_value.tv_sec -= itp->it_value.tv_sec; 381979Swnj else { 39*12977Ssam itp->it_value = oitv.it_value; 40*12977Ssam /* 41*12977Ssam * Set the reset value to the smallest possible, 42*12977Ssam * the system will round it to the clock resolution. 43*12977Ssam */ 44*12977Ssam oitv.it_value.tv_sec = 0; 45*12977Ssam oitv.it_value.tv_usec = 1; 461979Swnj } 471979Swnj } 48*12977Ssam setvec(vec, sleepx); 49*12977Ssam (void) sigvec(SIGALRM, &vec, &ovec); 50*12977Ssam if (setitimer(ITIMER_REAL, itp, (struct itimerval *)0) < 0) 51*12977Ssam longjmp(jmp, 1); 52*12977Ssam sigpause(omask &~ mask(SIGALRM)); 531979Swnj /*NOTREACHED*/ 541979Swnj } 551979Swnj 561979Swnj static 571979Swnj sleepx() 581979Swnj { 59*12977Ssam 601979Swnj longjmp(jmp, 1); 611979Swnj } 62