14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1982-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * David Korn <dgk@research.att.com> *
184887Schin * *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin * sleep delay
234887Schin *
244887Schin * David Korn
254887Schin * AT&T Labs
264887Schin *
274887Schin */
284887Schin
294887Schin #define sleep ______sleep
304887Schin #include "defs.h"
314887Schin #undef sleep
324887Schin #include <error.h>
334887Schin #include <errno.h>
3410898Sroland.mainz@nrubsig.org #include <tmx.h>
354887Schin #include "builtins.h"
364887Schin #include "FEATURE/time"
374887Schin #include "FEATURE/poll"
384887Schin #ifdef _NEXT_SOURCE
394887Schin # define sleep _ast_sleep
404887Schin #endif /* _NEXT_SOURCE */
414887Schin #ifdef _lib_poll_notimer
424887Schin # undef _lib_poll
434887Schin #endif /* _lib_poll_notimer */
444887Schin
b_sleep(register int argc,char * argv[],void * extra)454887Schin int b_sleep(register int argc,char *argv[],void *extra)
464887Schin {
474887Schin register char *cp;
4810898Sroland.mainz@nrubsig.org register double d=0;
498462SApril.Chin@Sun.COM register Shell_t *shp = ((Shbltin_t*)extra)->shp;
5010898Sroland.mainz@nrubsig.org int sflag=0;
514887Schin time_t tloc = 0;
528462SApril.Chin@Sun.COM char *last;
538462SApril.Chin@Sun.COM if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
548462SApril.Chin@Sun.COM sh_sigtrap(SIGALRM);
554887Schin while((argc = optget(argv,sh_optsleep))) switch(argc)
564887Schin {
5710898Sroland.mainz@nrubsig.org case 's':
5810898Sroland.mainz@nrubsig.org sflag=1;
5910898Sroland.mainz@nrubsig.org break;
604887Schin case ':':
614887Schin errormsg(SH_DICT,2, "%s", opt_info.arg);
624887Schin break;
634887Schin case '?':
644887Schin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
654887Schin break;
664887Schin }
674887Schin argv += opt_info.index;
6810898Sroland.mainz@nrubsig.org if(cp = *argv)
6910898Sroland.mainz@nrubsig.org {
7010898Sroland.mainz@nrubsig.org d = strtod(cp, &last);
7110898Sroland.mainz@nrubsig.org if(*last)
7210898Sroland.mainz@nrubsig.org {
7310898Sroland.mainz@nrubsig.org Time_t now,ns;
7410898Sroland.mainz@nrubsig.org char* pp;
7510898Sroland.mainz@nrubsig.org now = TMX_NOW;
7610898Sroland.mainz@nrubsig.org if(*cp == 'P' || *cp == 'p')
7710898Sroland.mainz@nrubsig.org ns = tmxdate(cp, &last, now);
7810898Sroland.mainz@nrubsig.org else
7910898Sroland.mainz@nrubsig.org {
8010898Sroland.mainz@nrubsig.org if(pp = sfprints("exact %s", cp))
8110898Sroland.mainz@nrubsig.org ns = tmxdate(pp, &last, now);
8210898Sroland.mainz@nrubsig.org if(*last && (pp = sfprints("p%s", cp)))
8310898Sroland.mainz@nrubsig.org ns = tmxdate(pp, &last, now);
8410898Sroland.mainz@nrubsig.org }
8510898Sroland.mainz@nrubsig.org if(*last)
8610898Sroland.mainz@nrubsig.org errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
8710898Sroland.mainz@nrubsig.org d = ns - now;
8810898Sroland.mainz@nrubsig.org d /= TMX_RESOLUTION;
8910898Sroland.mainz@nrubsig.org }
9010898Sroland.mainz@nrubsig.org if(argv[1])
9110898Sroland.mainz@nrubsig.org errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
9210898Sroland.mainz@nrubsig.org }
9310898Sroland.mainz@nrubsig.org else if(!sflag)
9410898Sroland.mainz@nrubsig.org errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
958462SApril.Chin@Sun.COM if(d > .10)
964887Schin {
974887Schin time(&tloc);
984887Schin tloc += (time_t)(d+.5);
994887Schin }
10010898Sroland.mainz@nrubsig.org if(sflag && d==0)
10110898Sroland.mainz@nrubsig.org pause();
10210898Sroland.mainz@nrubsig.org else while(1)
1034887Schin {
1044887Schin time_t now;
1054887Schin errno = 0;
1064887Schin shp->lastsig=0;
1074887Schin sh_delay(d);
10810898Sroland.mainz@nrubsig.org if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
1094887Schin break;
1104887Schin sh_sigcheck();
1114887Schin if(tloc < (now=time(NIL(time_t*))))
1124887Schin break;
1134887Schin d = (double)(tloc-now);
1144887Schin if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
1154887Schin sh_timetraps();
1164887Schin }
1174887Schin return(0);
1184887Schin }
1194887Schin
completed(void * handle)1204887Schin static void completed(void * handle)
1214887Schin {
1224887Schin char *expired = (char*)handle;
1234887Schin *expired = 1;
1244887Schin }
1254887Schin
sleep(unsigned int sec)1264887Schin unsigned int sleep(unsigned int sec)
1274887Schin {
1288462SApril.Chin@Sun.COM Shell_t *shp = &sh;
1294887Schin pid_t newpid, curpid=getpid();
1304887Schin void *tp;
1314887Schin char expired = 0;
1328462SApril.Chin@Sun.COM shp->lastsig = 0;
1334887Schin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
1344887Schin do
1354887Schin {
1368462SApril.Chin@Sun.COM if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0)
1374887Schin pause();
1388462SApril.Chin@Sun.COM if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
1394887Schin sh_timetraps();
1404887Schin if((newpid=getpid()) != curpid)
1414887Schin {
1424887Schin curpid = newpid;
1438462SApril.Chin@Sun.COM shp->lastsig = 0;
1448462SApril.Chin@Sun.COM shp->trapnote &= ~SH_SIGSET;
1454887Schin if(expired)
1464887Schin expired = 0;
1474887Schin else
1484887Schin timerdel(tp);
1494887Schin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
1504887Schin }
1514887Schin }
1528462SApril.Chin@Sun.COM while(!expired && shp->lastsig==0);
1534887Schin if(!expired)
1544887Schin timerdel(tp);
1554887Schin sh_sigcheck();
1564887Schin return(0);
1574887Schin }
1584887Schin
1594887Schin /*
1604887Schin * delay execution for time <t>
1614887Schin */
1624887Schin
sh_delay(double t)1634887Schin void sh_delay(double t)
1644887Schin {
1654887Schin register int n = (int)t;
1668462SApril.Chin@Sun.COM Shell_t *shp = &sh;
1674887Schin #ifdef _lib_poll
1684887Schin struct pollfd fd;
1694887Schin if(t<=0)
1704887Schin return;
1714887Schin else if(n > 30)
1724887Schin {
1734887Schin sleep(n);
1744887Schin t -= n;
1754887Schin }
1764887Schin if(n=(int)(1000*t))
1774887Schin {
1788462SApril.Chin@Sun.COM if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
1794887Schin poll(&fd,0,n);
1804887Schin }
1814887Schin #else
1824887Schin # if defined(_lib_select) && defined(_mem_tv_usec_timeval)
1834887Schin struct timeval timeloc;
1844887Schin if(t<=0)
1854887Schin return;
1868462SApril.Chin@Sun.COM if(n=(int)(1000*t) && shp->waitevent && (*shp->waitevent)(-1,(long)n,0))
1874887Schin return;
1884887Schin n = (int)t;
1894887Schin timeloc.tv_sec = n;
1904887Schin timeloc.tv_usec = 1000000*(t-(double)n);
1914887Schin select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc);
1924887Schin # else
1934887Schin # ifdef _lib_select
1944887Schin /* for 9th edition machines */
1954887Schin if(t<=0)
1964887Schin return;
1974887Schin if(n > 30)
1984887Schin {
1994887Schin sleep(n);
2004887Schin t -= n;
2014887Schin }
2024887Schin if(n=(int)(1000*t))
2034887Schin {
2048462SApril.Chin@Sun.COM if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
2054887Schin select(0,(fd_set*)0,(fd_set*)0,n);
2064887Schin }
2074887Schin # else
2084887Schin struct tms tt;
2094887Schin if(t<=0)
2104887Schin return;
2114887Schin sleep(n);
2124887Schin t -= n;
2134887Schin if(t)
2144887Schin {
2154887Schin clock_t begin = times(&tt);
2164887Schin if(begin==0)
2174887Schin return;
2188462SApril.Chin@Sun.COM t *= shp->lim.clk_tck;
2194887Schin n += (t+.5);
2204887Schin while((times(&tt)-begin) < n);
2214887Schin }
2224887Schin # endif
2234887Schin # endif
2244887Schin #endif /* _lib_poll */
2254887Schin }
226