1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2013 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 <dgkorn@gmail.com> *
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
b_sleep(register int argc,char * argv[],void * extra)45 int b_sleep(register int argc,char *argv[],void *extra)
46 {
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)
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
79 {
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);
84 }
85 if(*last)
86 errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
87 d = ns - now;
88 d /= TMX_RESOLUTION;
89 }
90 if(argv[1])
91 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
92 }
93 else if(!sflag)
94 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
95 if(d > .10)
96 {
97 time(&tloc);
98 tloc += (time_t)(d+.5);
99 }
100 if(sflag && d==0)
101 pause();
102 else while(1)
103 {
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();
116 }
117 return(0);
118 }
119
completed(void * handle)120 static void completed(void * handle)
121 {
122 char *expired = (char*)handle;
123 *expired = 1;
124 }
125
sleep(unsigned int sec)126 unsigned int sleep(unsigned int sec)
127 {
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);
134 do
135 {
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)
141 {
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);
150 }
151 }
152 while(!expired && shp->lastsig==0);
153 if(!expired)
154 timerdel(tp);
155 sh_sigcheck();
156 return(0);
157 }
158
159 //
160 // Delay execution for time <t>.
161 //
sh_delay(double t)162 void sh_delay(double t) {
163 Shell_t *shp = sh_getinterp();
164 int n = (int)t;
165 Tv_t ts, tx;
166
167 ts.tv_sec = n;
168 ts.tv_nsec = 1000000000 * (t - (double)n);
169 while (tvsleep(&ts, &tx) < 0 && errno == EINTR) {
170 if (shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) return;
171 ts = tx;
172 }
173 }
174