2 * Copyright 1986 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * Copyright (c) 1980 Regents of the University of California.
8 * All rights reserved. The Berkeley software License Agreement
9 * specifies the terms and conditions for redistribution.
12 #pragma ident "%Z%%M% %I% %E% SMI"
17 #define setvec(vec, a) \
18 vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
20 static void sleepx(void);
25 * return 0 if n seconds passed
26 * return n - t if t seconds passed
28 * this code is gross and works just barely.
29 * it would be nice if someone rewrote it.
35 struct itimerval
new, old
, zero
;
36 struct itimerval
*newp
= &new;
37 struct timeval left_over
;
39 struct sigvec vec
, ovec
;
43 timerclear(&newp
->it_interval
);
44 timerclear(&newp
->it_value
);
45 if (setitimer(ITIMER_REAL
, newp
, &old
) < 0)
47 newp
->it_value
.tv_sec
= n
;
49 timerclear(&left_over
);
50 if (timerisset(&old
.it_value
)) {
51 if (timercmp(&old
.it_value
, &newp
->it_value
, >)) {
52 old
.it_value
.tv_sec
-= newp
->it_value
.tv_sec
;
55 left_over
.tv_sec
= newp
->it_value
.tv_sec
56 - old
.it_value
.tv_sec
;
57 if (old
.it_value
.tv_usec
!= 0) {
59 left_over
.tv_usec
= 1000000
60 - old
.it_value
.tv_usec
;
62 newp
->it_value
= old
.it_value
;
63 timerclear(&old
.it_value
);
69 (void) sigvec(SIGALRM
, &vec
, &ovec
);
71 omask
= sigblock(sigmask(SIGALRM
));
72 (void) setitimer(ITIMER_REAL
, newp
, (struct itimerval
*)0);
73 sigpause(omask
&~ sigmask(SIGALRM
));
74 timerclear(&zero
.it_value
);
75 timerclear(&zero
.it_interval
);
76 (void) setitimer(ITIMER_REAL
, &zero
, newp
);
78 (void) sigvec(SIGALRM
, &ovec
, (struct sigvec
*)0);
79 (void) sigsetmask(omask
);
80 if (alrm_flg
> 0 || (alrm_flg
< 0 && timerisset(&newp
->it_value
))) {
81 struct itimerval reset
;
84 * I use reset instead of what new points to because the
85 * code that calculates the return value depends on the
90 newp
->it_value
.tv_usec
+= old
.it_value
.tv_usec
;
91 newp
->it_value
.tv_sec
+= old
.it_value
.tv_sec
;
92 if (newp
->it_value
.tv_usec
>= 1000000) {
93 newp
->it_value
.tv_usec
-= 1000000;
94 newp
->it_value
.tv_sec
++;
96 (void) setitimer(ITIMER_REAL
, newp
, (struct itimerval
*)0);
99 left_over
.tv_sec
+= newp
->it_value
.tv_sec
;
100 left_over
.tv_usec
+= newp
->it_value
.tv_usec
;
101 if (left_over
.tv_usec
>= 1000000) {
103 left_over
.tv_usec
-= 1000000;
105 if (left_over
.tv_usec
>= 500000)
107 return(left_over
.tv_sec
);