8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libshell / common / bltins / sleep.c
blob6121cfe62bd07c57877acdf9c7a4052484a7fe59
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * David Korn <dgk@research.att.com> *
18 * *
19 ***********************************************************************/
20 #pragma prototyped
22 * sleep delay
24 * David Korn
25 * AT&T Labs
29 #define sleep ______sleep
30 #include "defs.h"
31 #undef sleep
32 #include <error.h>
33 #include <errno.h>
34 #include <tmx.h>
35 #include "builtins.h"
36 #include "FEATURE/time"
37 #include "FEATURE/poll"
38 #ifdef _NEXT_SOURCE
39 # define sleep _ast_sleep
40 #endif /* _NEXT_SOURCE */
41 #ifdef _lib_poll_notimer
42 # undef _lib_poll
43 #endif /* _lib_poll_notimer */
45 int b_sleep(register int argc,char *argv[],void *extra)
47 register char *cp;
48 register double d=0;
49 register Shell_t *shp = ((Shbltin_t*)extra)->shp;
50 int sflag=0;
51 time_t tloc = 0;
52 char *last;
53 if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
54 sh_sigtrap(SIGALRM);
55 while((argc = optget(argv,sh_optsleep))) switch(argc)
57 case 's':
58 sflag=1;
59 break;
60 case ':':
61 errormsg(SH_DICT,2, "%s", opt_info.arg);
62 break;
63 case '?':
64 errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
65 break;
67 argv += opt_info.index;
68 if(cp = *argv)
70 d = strtod(cp, &last);
71 if(*last)
73 Time_t now,ns;
74 char* pp;
75 now = TMX_NOW;
76 if(*cp == 'P' || *cp == 'p')
77 ns = tmxdate(cp, &last, now);
78 else
80 if(pp = sfprints("exact %s", cp))
81 ns = tmxdate(pp, &last, now);
82 if(*last && (pp = sfprints("p%s", cp)))
83 ns = tmxdate(pp, &last, now);
85 if(*last)
86 errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
87 d = ns - now;
88 d /= TMX_RESOLUTION;
90 if(argv[1])
91 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
93 else if(!sflag)
94 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
95 if(d > .10)
97 time(&tloc);
98 tloc += (time_t)(d+.5);
100 if(sflag && d==0)
101 pause();
102 else while(1)
104 time_t now;
105 errno = 0;
106 shp->lastsig=0;
107 sh_delay(d);
108 if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
109 break;
110 sh_sigcheck();
111 if(tloc < (now=time(NIL(time_t*))))
112 break;
113 d = (double)(tloc-now);
114 if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
115 sh_timetraps();
117 return(0);
120 static void completed(void * handle)
122 char *expired = (char*)handle;
123 *expired = 1;
126 unsigned int sleep(unsigned int sec)
128 Shell_t *shp = &sh;
129 pid_t newpid, curpid=getpid();
130 void *tp;
131 char expired = 0;
132 shp->lastsig = 0;
133 tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
136 if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0)
137 pause();
138 if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
139 sh_timetraps();
140 if((newpid=getpid()) != curpid)
142 curpid = newpid;
143 shp->lastsig = 0;
144 shp->trapnote &= ~SH_SIGSET;
145 if(expired)
146 expired = 0;
147 else
148 timerdel(tp);
149 tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
152 while(!expired && shp->lastsig==0);
153 if(!expired)
154 timerdel(tp);
155 sh_sigcheck();
156 return(0);
160 * delay execution for time <t>
163 void sh_delay(double t)
165 register int n = (int)t;
166 Shell_t *shp = &sh;
167 #ifdef _lib_poll
168 struct pollfd fd;
169 if(t<=0)
170 return;
171 else if(n > 30)
173 sleep(n);
174 t -= n;
176 if(n=(int)(1000*t))
178 if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
179 poll(&fd,0,n);
181 #else
182 # if defined(_lib_select) && defined(_mem_tv_usec_timeval)
183 struct timeval timeloc;
184 if(t<=0)
185 return;
186 if(n=(int)(1000*t) && shp->waitevent && (*shp->waitevent)(-1,(long)n,0))
187 return;
188 n = (int)t;
189 timeloc.tv_sec = n;
190 timeloc.tv_usec = 1000000*(t-(double)n);
191 select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc);
192 # else
193 # ifdef _lib_select
194 /* for 9th edition machines */
195 if(t<=0)
196 return;
197 if(n > 30)
199 sleep(n);
200 t -= n;
202 if(n=(int)(1000*t))
204 if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
205 select(0,(fd_set*)0,(fd_set*)0,n);
207 # else
208 struct tms tt;
209 if(t<=0)
210 return;
211 sleep(n);
212 t -= n;
213 if(t)
215 clock_t begin = times(&tt);
216 if(begin==0)
217 return;
218 t *= shp->lim.clk_tck;
219 n += (t+.5);
220 while((times(&tt)-begin) < n);
222 # endif
223 # endif
224 #endif /* _lib_poll */