manual page distributed with 4.1BSD
[unix-history] / usr / src / lib / libc / gen / sleep.c
CommitLineData
455b164d 1#ifndef lint
1c9de88b 2static 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
11static int ringring;
12
cc749e07 13sleep(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
55static
56sleepx()
57{
fa95c6ae 58
e15ec383 59 ringring = 1;
cc749e07 60}