1da2e3ebdSchin /***********************************************************************
25947648bSMarcel Telka * *
35947648bSMarcel Telka * This software is part of the ast package *
45947648bSMarcel Telka * Copyright (c) 1982-2013 AT&T Intellectual Property *
55947648bSMarcel Telka * and is licensed under the *
65947648bSMarcel Telka * Eclipse Public License, Version 1.0 *
75947648bSMarcel Telka * by AT&T Intellectual Property *
85947648bSMarcel Telka * *
95947648bSMarcel Telka * A copy of the License is available at *
105947648bSMarcel Telka * http://www.eclipse.org/org/documents/epl-v10.html *
115947648bSMarcel Telka * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
125947648bSMarcel Telka * *
135947648bSMarcel Telka * Information and Software Systems Research *
145947648bSMarcel Telka * AT&T Research *
155947648bSMarcel Telka * Florham Park NJ *
165947648bSMarcel Telka * *
175947648bSMarcel Telka * David Korn <dgkorn@gmail.com> *
185947648bSMarcel Telka * *
195947648bSMarcel Telka ***********************************************************************/
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[],Shbltin_t * context)45*b30d1939SAndy Fiddaman int b_sleep(register int argc,char *argv[],Shbltin_t *context)
46da2e3ebdSchin {
47da2e3ebdSchin register char *cp;
4834f9b3eeSRoland Mainz register double d=0;
49*b30d1939SAndy Fiddaman register Shell_t *shp = context->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);
78*b30d1939SAndy Fiddaman else if(*last=='.' && shp->decomma && d==(unsigned long)d)
79*b30d1939SAndy Fiddaman {
80*b30d1939SAndy Fiddaman *(pp=last) = ',';
81*b30d1939SAndy Fiddaman if(!strchr(cp,'.'))
82*b30d1939SAndy Fiddaman d = strtod(cp,&last);
83*b30d1939SAndy Fiddaman *pp = '.';
84*b30d1939SAndy Fiddaman if(*last==0)
85*b30d1939SAndy Fiddaman goto skip;
86*b30d1939SAndy Fiddaman }
87*b30d1939SAndy Fiddaman else if(*last!='.' && *last!=',')
8834f9b3eeSRoland Mainz {
8934f9b3eeSRoland Mainz if(pp = sfprints("exact %s", cp))
9034f9b3eeSRoland Mainz ns = tmxdate(pp, &last, now);
9134f9b3eeSRoland Mainz if(*last && (pp = sfprints("p%s", cp)))
9234f9b3eeSRoland Mainz ns = tmxdate(pp, &last, now);
9334f9b3eeSRoland Mainz }
9434f9b3eeSRoland Mainz if(*last)
9534f9b3eeSRoland Mainz errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
9634f9b3eeSRoland Mainz d = ns - now;
9734f9b3eeSRoland Mainz d /= TMX_RESOLUTION;
9834f9b3eeSRoland Mainz }
99*b30d1939SAndy Fiddaman skip:
10034f9b3eeSRoland Mainz if(argv[1])
10134f9b3eeSRoland Mainz errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
10234f9b3eeSRoland Mainz }
10334f9b3eeSRoland Mainz else if(!sflag)
10434f9b3eeSRoland Mainz errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
1057c2fbfb3SApril Chin if(d > .10)
106da2e3ebdSchin {
107da2e3ebdSchin time(&tloc);
108da2e3ebdSchin tloc += (time_t)(d+.5);
109da2e3ebdSchin }
11034f9b3eeSRoland Mainz if(sflag && d==0)
11134f9b3eeSRoland Mainz pause();
11234f9b3eeSRoland Mainz else while(1)
113da2e3ebdSchin {
114da2e3ebdSchin time_t now;
115da2e3ebdSchin errno = 0;
116da2e3ebdSchin shp->lastsig=0;
117da2e3ebdSchin sh_delay(d);
11834f9b3eeSRoland Mainz if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
119da2e3ebdSchin break;
120*b30d1939SAndy Fiddaman sh_sigcheck(shp);
121da2e3ebdSchin if(tloc < (now=time(NIL(time_t*))))
122da2e3ebdSchin break;
123da2e3ebdSchin d = (double)(tloc-now);
124da2e3ebdSchin if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
125*b30d1939SAndy Fiddaman sh_timetraps(shp);
126da2e3ebdSchin }
127da2e3ebdSchin return(0);
128da2e3ebdSchin }
129da2e3ebdSchin
completed(void * handle)130da2e3ebdSchin static void completed(void * handle)
131da2e3ebdSchin {
132da2e3ebdSchin char *expired = (char*)handle;
133da2e3ebdSchin *expired = 1;
134da2e3ebdSchin }
135da2e3ebdSchin
sleep(unsigned int sec)136da2e3ebdSchin unsigned int sleep(unsigned int sec)
137da2e3ebdSchin {
138*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
139da2e3ebdSchin pid_t newpid, curpid=getpid();
140da2e3ebdSchin void *tp;
141da2e3ebdSchin char expired = 0;
1427c2fbfb3SApril Chin shp->lastsig = 0;
143da2e3ebdSchin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
144da2e3ebdSchin do
145da2e3ebdSchin {
146*b30d1939SAndy Fiddaman if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,-1L,0)==0)
147da2e3ebdSchin pause();
1487c2fbfb3SApril Chin if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
149*b30d1939SAndy Fiddaman sh_timetraps(shp);
150da2e3ebdSchin if((newpid=getpid()) != curpid)
151da2e3ebdSchin {
152da2e3ebdSchin curpid = newpid;
1537c2fbfb3SApril Chin shp->lastsig = 0;
1547c2fbfb3SApril Chin shp->trapnote &= ~SH_SIGSET;
155da2e3ebdSchin if(expired)
156da2e3ebdSchin expired = 0;
157da2e3ebdSchin else
158da2e3ebdSchin timerdel(tp);
159da2e3ebdSchin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
160da2e3ebdSchin }
161da2e3ebdSchin }
1627c2fbfb3SApril Chin while(!expired && shp->lastsig==0);
163da2e3ebdSchin if(!expired)
164da2e3ebdSchin timerdel(tp);
165*b30d1939SAndy Fiddaman sh_sigcheck(shp);
166da2e3ebdSchin return(0);
167da2e3ebdSchin }
168da2e3ebdSchin
1695947648bSMarcel Telka //
1705947648bSMarcel Telka // Delay execution for time <t>.
1715947648bSMarcel Telka //
sh_delay(double t)1725947648bSMarcel Telka void sh_delay(double t) {
1735947648bSMarcel Telka Shell_t *shp = sh_getinterp();
1745947648bSMarcel Telka int n = (int)t;
1755947648bSMarcel Telka Tv_t ts, tx;
176da2e3ebdSchin
1775947648bSMarcel Telka ts.tv_sec = n;
1785947648bSMarcel Telka ts.tv_nsec = 1000000000 * (t - (double)n);
1795947648bSMarcel Telka while (tvsleep(&ts, &tx) < 0 && errno == EINTR) {
1805947648bSMarcel Telka if (shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) return;
1815947648bSMarcel Telka ts = tx;
1825947648bSMarcel Telka }
183*b30d1939SAndy Fiddaman }
184