Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ksh93/bltins/sleep.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1982-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* David Korn <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* sleep delay
23
*
24
* David Korn
25
* AT&T Labs
26
*
27
*/
28
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 */
44
45
int b_sleep(register int argc,char *argv[],Shbltin_t *context)
46
{
47
register char *cp;
48
register double d=0;
49
register Shell_t *shp = context->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)
56
{
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;
66
}
67
argv += opt_info.index;
68
if(cp = *argv)
69
{
70
d = strtod(cp, &last);
71
if(*last)
72
{
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 if(*last=='.' && shp->decomma && d==(unsigned long)d)
79
{
80
*(pp=last) = ',';
81
if(!strchr(cp,'.'))
82
d = strtod(cp,&last);
83
*pp = '.';
84
if(*last==0)
85
goto skip;
86
}
87
else if(*last!='.' && *last!=',')
88
{
89
if(pp = sfprints("exact %s", cp))
90
ns = tmxdate(pp, &last, now);
91
if(*last && (pp = sfprints("p%s", cp)))
92
ns = tmxdate(pp, &last, now);
93
}
94
if(*last)
95
errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
96
d = ns - now;
97
d /= TMX_RESOLUTION;
98
}
99
skip:
100
if(argv[1])
101
errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
102
}
103
else if(!sflag)
104
errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
105
if(d > .10)
106
{
107
time(&tloc);
108
tloc += (time_t)(d+.5);
109
}
110
if(sflag && d==0)
111
pause();
112
else while(1)
113
{
114
time_t now;
115
errno = 0;
116
shp->lastsig=0;
117
sh_delay(d);
118
if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
119
break;
120
sh_sigcheck(shp);
121
if(tloc < (now=time(NIL(time_t*))))
122
break;
123
d = (double)(tloc-now);
124
if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
125
sh_timetraps(shp);
126
}
127
return(0);
128
}
129
130
static void completed(void * handle)
131
{
132
char *expired = (char*)handle;
133
*expired = 1;
134
}
135
136
unsigned int sleep(unsigned int sec)
137
{
138
Shell_t *shp = sh_getinterp();
139
pid_t newpid, curpid=getpid();
140
void *tp;
141
char expired = 0;
142
shp->lastsig = 0;
143
tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
144
do
145
{
146
if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,-1L,0)==0)
147
pause();
148
if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
149
sh_timetraps(shp);
150
if((newpid=getpid()) != curpid)
151
{
152
curpid = newpid;
153
shp->lastsig = 0;
154
shp->trapnote &= ~SH_SIGSET;
155
if(expired)
156
expired = 0;
157
else
158
timerdel(tp);
159
tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
160
}
161
}
162
while(!expired && shp->lastsig==0);
163
if(!expired)
164
timerdel(tp);
165
sh_sigcheck(shp);
166
return(0);
167
}
168
169
/*
170
* delay execution for time <t>
171
*/
172
173
void sh_delay(double t)
174
{
175
register int n = (int)t;
176
Shell_t *shp = sh_getinterp();
177
#ifdef _lib_poll
178
struct pollfd fd;
179
if(t<=0)
180
return;
181
else if(n > 30)
182
{
183
sleep(n);
184
t -= n;
185
}
186
if(n=(int)(1000*t))
187
{
188
if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,(long)n,0)==0)
189
poll(&fd,0,n);
190
}
191
#else
192
# if defined(_lib_select) && defined(_mem_tv_usec_timeval)
193
struct timeval timeloc;
194
if(t<=0)
195
return;
196
if(n=(int)(1000*t) && shp->gd->waitevent && (*shp->gd->waitevent)(-1,(long)n,0))
197
return;
198
n = (int)t;
199
timeloc.tv_sec = n;
200
timeloc.tv_usec = 1000000*(t-(double)n);
201
select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc);
202
# else
203
# ifdef _lib_select
204
/* for 9th edition machines */
205
if(t<=0)
206
return;
207
if(n > 30)
208
{
209
sleep(n);
210
t -= n;
211
}
212
if(n=(int)(1000*t))
213
{
214
if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,(long)n,0)==0)
215
select(0,(fd_set*)0,(fd_set*)0,n);
216
}
217
# else
218
struct tms tt;
219
if(t<=0)
220
return;
221
sleep(n);
222
t -= n;
223
if(t)
224
{
225
clock_t begin = times(&tt);
226
if(begin==0)
227
return;
228
t *= shp->gd->lim.clk_tck;
229
n += (t+.5);
230
while((times(&tt)-begin) < n);
231
}
232
# endif
233
# endif
234
#endif /* _lib_poll */
235
}
236
237