xref: /csrg-svn/lib/libc/gen/sleep.c (revision 12977)
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