Commit | Line | Data |
---|---|---|
455b164d | 1 | #ifndef lint |
1c9de88b | 2 | static char sccsid[] = "@(#)sleep.c 4.7 (Berkeley) %G%"; |
455b164d | 3 | #endif |
fa95c6ae | 4 | |
455b164d | 5 | #include <sys/time.h> |
cc749e07 | 6 | #include <signal.h> |
cc749e07 | 7 | |
fa95c6ae SL |
8 | #define setvec(vec, a) \ |
9 | vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 | |
10 | ||
e15ec383 MK |
11 | static int ringring; |
12 | ||
cc749e07 | 13 | sleep(n) |
fa95c6ae | 14 | unsigned n; |
cc749e07 | 15 | { |
fa95c6ae SL |
16 | int sleepx(), omask; |
17 | struct itimerval itv, oitv; | |
18 | register struct itimerval *itp = &itv; | |
19 | struct sigvec vec, ovec; | |
cc749e07 | 20 | |
fa95c6ae | 21 | if (n == 0) |
cc749e07 | 22 | return; |
fa95c6ae SL |
23 | timerclear(&itp->it_interval); |
24 | timerclear(&itp->it_value); | |
25 | if (setitimer(ITIMER_REAL, itp, &oitv) < 0) | |
26 | return; | |
fa95c6ae SL |
27 | itp->it_value.tv_sec = n; |
28 | if (timerisset(&oitv.it_value)) { | |
29 | if (timercmp(&oitv.it_value, &itp->it_value, >)) | |
30 | oitv.it_value.tv_sec -= itp->it_value.tv_sec; | |
cc749e07 | 31 | else { |
fa95c6ae SL |
32 | itp->it_value = oitv.it_value; |
33 | /* | |
a883f51a | 34 | * This is a hack, but we must have time to |
e15ec383 | 35 | * return from the setitimer after the alarm |
a883f51a SL |
36 | * or else it'll be restarted. And, anyway, |
37 | * sleep never did anything more than this before. | |
fa95c6ae | 38 | */ |
a883f51a SL |
39 | oitv.it_value.tv_sec = 1; |
40 | oitv.it_value.tv_usec = 0; | |
cc749e07 BJ |
41 | } |
42 | } | |
fa95c6ae SL |
43 | setvec(vec, sleepx); |
44 | (void) sigvec(SIGALRM, &vec, &ovec); | |
1c9de88b | 45 | omask = sigblock(sigmask(SIGALRM)); |
e15ec383 | 46 | ringring = 0; |
b34945c3 | 47 | (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); |
e15ec383 | 48 | while (!ringring) |
1c9de88b | 49 | sigpause(omask &~ sigmask(SIGALRM)); |
e15ec383 | 50 | (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); |
1c9de88b | 51 | (void) sigsetmask(omask); |
e15ec383 | 52 | (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); |
cc749e07 BJ |
53 | } |
54 | ||
55 | static | |
56 | sleepx() | |
57 | { | |
fa95c6ae | 58 | |
e15ec383 | 59 | ringring = 1; |
cc749e07 | 60 | } |