1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*2777f608SMarcel Telka * Copyright (c) 1982-2013 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6*2777f608SMarcel Telka * Eclipse Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10*2777f608SMarcel Telka * http://www.eclipse.org/org/documents/epl-v10.html *
11*2777f608SMarcel Telka * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17*2777f608SMarcel Telka * David Korn <dgkorn@gmail.com> *
18da2e3ebdSchin * *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /*
22da2e3ebdSchin * sleep delay
23da2e3ebdSchin *
24da2e3ebdSchin * David Korn
25da2e3ebdSchin * AT&T Labs
26da2e3ebdSchin *
27da2e3ebdSchin */
28da2e3ebdSchin
29da2e3ebdSchin #define sleep ______sleep
30da2e3ebdSchin #include "defs.h"
31da2e3ebdSchin #undef sleep
32da2e3ebdSchin #include <error.h>
33da2e3ebdSchin #include <errno.h>
3434f9b3eeSRoland Mainz #include <tmx.h>
35da2e3ebdSchin #include "builtins.h"
36da2e3ebdSchin #include "FEATURE/time"
37da2e3ebdSchin #include "FEATURE/poll"
38da2e3ebdSchin #ifdef _NEXT_SOURCE
39da2e3ebdSchin # define sleep _ast_sleep
40da2e3ebdSchin #endif /* _NEXT_SOURCE */
41da2e3ebdSchin #ifdef _lib_poll_notimer
42da2e3ebdSchin # undef _lib_poll
43da2e3ebdSchin #endif /* _lib_poll_notimer */
44da2e3ebdSchin
b_sleep(register int argc,char * argv[],void * extra)45da2e3ebdSchin int b_sleep(register int argc,char *argv[],void *extra)
46da2e3ebdSchin {
47da2e3ebdSchin register char *cp;
4834f9b3eeSRoland Mainz register double d=0;
497c2fbfb3SApril Chin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
5034f9b3eeSRoland Mainz int sflag=0;
51da2e3ebdSchin time_t tloc = 0;
527c2fbfb3SApril Chin char *last;
537c2fbfb3SApril Chin if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
547c2fbfb3SApril Chin sh_sigtrap(SIGALRM);
55da2e3ebdSchin while((argc = optget(argv,sh_optsleep))) switch(argc)
56da2e3ebdSchin {
5734f9b3eeSRoland Mainz case 's':
5834f9b3eeSRoland Mainz sflag=1;
5934f9b3eeSRoland Mainz break;
60da2e3ebdSchin case ':':
61da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
62da2e3ebdSchin break;
63da2e3ebdSchin case '?':
64da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
65da2e3ebdSchin break;
66da2e3ebdSchin }
67da2e3ebdSchin argv += opt_info.index;
6834f9b3eeSRoland Mainz if(cp = *argv)
6934f9b3eeSRoland Mainz {
7034f9b3eeSRoland Mainz d = strtod(cp, &last);
7134f9b3eeSRoland Mainz if(*last)
7234f9b3eeSRoland Mainz {
7334f9b3eeSRoland Mainz Time_t now,ns;
7434f9b3eeSRoland Mainz char* pp;
7534f9b3eeSRoland Mainz now = TMX_NOW;
7634f9b3eeSRoland Mainz if(*cp == 'P' || *cp == 'p')
7734f9b3eeSRoland Mainz ns = tmxdate(cp, &last, now);
7834f9b3eeSRoland Mainz else
7934f9b3eeSRoland Mainz {
8034f9b3eeSRoland Mainz if(pp = sfprints("exact %s", cp))
8134f9b3eeSRoland Mainz ns = tmxdate(pp, &last, now);
8234f9b3eeSRoland Mainz if(*last && (pp = sfprints("p%s", cp)))
8334f9b3eeSRoland Mainz ns = tmxdate(pp, &last, now);
8434f9b3eeSRoland Mainz }
8534f9b3eeSRoland Mainz if(*last)
8634f9b3eeSRoland Mainz errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
8734f9b3eeSRoland Mainz d = ns - now;
8834f9b3eeSRoland Mainz d /= TMX_RESOLUTION;
8934f9b3eeSRoland Mainz }
9034f9b3eeSRoland Mainz if(argv[1])
9134f9b3eeSRoland Mainz errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
9234f9b3eeSRoland Mainz }
9334f9b3eeSRoland Mainz else if(!sflag)
9434f9b3eeSRoland Mainz errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
957c2fbfb3SApril Chin if(d > .10)
96da2e3ebdSchin {
97da2e3ebdSchin time(&tloc);
98da2e3ebdSchin tloc += (time_t)(d+.5);
99da2e3ebdSchin }
10034f9b3eeSRoland Mainz if(sflag && d==0)
10134f9b3eeSRoland Mainz pause();
10234f9b3eeSRoland Mainz else while(1)
103da2e3ebdSchin {
104da2e3ebdSchin time_t now;
105da2e3ebdSchin errno = 0;
106da2e3ebdSchin shp->lastsig=0;
107da2e3ebdSchin sh_delay(d);
10834f9b3eeSRoland Mainz if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
109da2e3ebdSchin break;
110da2e3ebdSchin sh_sigcheck();
111da2e3ebdSchin if(tloc < (now=time(NIL(time_t*))))
112da2e3ebdSchin break;
113da2e3ebdSchin d = (double)(tloc-now);
114da2e3ebdSchin if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
115da2e3ebdSchin sh_timetraps();
116da2e3ebdSchin }
117da2e3ebdSchin return(0);
118da2e3ebdSchin }
119da2e3ebdSchin
completed(void * handle)120da2e3ebdSchin static void completed(void * handle)
121da2e3ebdSchin {
122da2e3ebdSchin char *expired = (char*)handle;
123da2e3ebdSchin *expired = 1;
124da2e3ebdSchin }
125da2e3ebdSchin
sleep(unsigned int sec)126da2e3ebdSchin unsigned int sleep(unsigned int sec)
127da2e3ebdSchin {
1287c2fbfb3SApril Chin Shell_t *shp = &sh;
129da2e3ebdSchin pid_t newpid, curpid=getpid();
130da2e3ebdSchin void *tp;
131da2e3ebdSchin char expired = 0;
1327c2fbfb3SApril Chin shp->lastsig = 0;
133da2e3ebdSchin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
134da2e3ebdSchin do
135da2e3ebdSchin {
1367c2fbfb3SApril Chin if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0)
137da2e3ebdSchin pause();
1387c2fbfb3SApril Chin if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
139da2e3ebdSchin sh_timetraps();
140da2e3ebdSchin if((newpid=getpid()) != curpid)
141da2e3ebdSchin {
142da2e3ebdSchin curpid = newpid;
1437c2fbfb3SApril Chin shp->lastsig = 0;
1447c2fbfb3SApril Chin shp->trapnote &= ~SH_SIGSET;
145da2e3ebdSchin if(expired)
146da2e3ebdSchin expired = 0;
147da2e3ebdSchin else
148da2e3ebdSchin timerdel(tp);
149da2e3ebdSchin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
150da2e3ebdSchin }
151da2e3ebdSchin }
1527c2fbfb3SApril Chin while(!expired && shp->lastsig==0);
153da2e3ebdSchin if(!expired)
154da2e3ebdSchin timerdel(tp);
155da2e3ebdSchin sh_sigcheck();
156da2e3ebdSchin return(0);
157da2e3ebdSchin }
158da2e3ebdSchin
159*2777f608SMarcel Telka //
160*2777f608SMarcel Telka // Delay execution for time <t>.
161*2777f608SMarcel Telka //
sh_delay(double t)162*2777f608SMarcel Telka void sh_delay(double t) {
163*2777f608SMarcel Telka Shell_t *shp = sh_getinterp();
164*2777f608SMarcel Telka int n = (int)t;
165*2777f608SMarcel Telka Tv_t ts, tx;
166da2e3ebdSchin
167*2777f608SMarcel Telka ts.tv_sec = n;
168*2777f608SMarcel Telka ts.tv_nsec = 1000000000 * (t - (double)n);
169*2777f608SMarcel Telka while (tvsleep(&ts, &tx) < 0 && errno == EINTR) {
170*2777f608SMarcel Telka if (shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) return;
171*2777f608SMarcel Telka ts = tx;
172da2e3ebdSchin }
173da2e3ebdSchin }
174