8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbc / libc / gen / sys5 / sleep.c
blob1e6dbbbc2939fb677a260d5a8650904483c3e829
1 /*
2 * Copyright 1986 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 /*
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"
14 #include <sys/time.h>
15 #include <signal.h>
17 #define setvec(vec, a) \
18 vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
20 static void sleepx(void);
23 * sleep(n)
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.
31 unsigned
32 sleep(unsigned n)
34 int omask;
35 struct itimerval new, old, zero;
36 struct itimerval *newp = &new;
37 struct timeval left_over;
38 int alrm_flg;
39 struct sigvec vec, ovec;
41 if (n == 0)
42 return(0);
43 timerclear(&newp->it_interval);
44 timerclear(&newp->it_value);
45 if (setitimer(ITIMER_REAL, newp, &old) < 0)
46 return(n);
47 newp->it_value.tv_sec = n;
48 alrm_flg = 0;
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;
53 ++alrm_flg;
54 } else {
55 left_over.tv_sec = newp->it_value.tv_sec
56 - old.it_value.tv_sec;
57 if (old.it_value.tv_usec != 0) {
58 left_over.tv_sec--;
59 left_over.tv_usec = 1000000
60 - old.it_value.tv_usec;
62 newp->it_value = old.it_value;
63 timerclear(&old.it_value);
64 --alrm_flg;
67 if (alrm_flg >= 0) {
68 setvec(vec, sleepx);
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);
77 if (alrm_flg >= 0)
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
86 * old value of *newp.
88 reset = *newp;
89 newp = &reset;
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);
97 newp = &new;
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) {
102 left_over.tv_sec++;
103 left_over.tv_usec -= 1000000;
105 if (left_over.tv_usec >= 500000)
106 left_over.tv_sec++;
107 return(left_over.tv_sec);
110 static void
111 sleepx(void)