14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*10898Sroland.mainz@nrubsig.org *          Copyright (c) 1982-2009 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>
34*10898Sroland.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 
454887Schin int	b_sleep(register int argc,char *argv[],void *extra)
464887Schin {
474887Schin 	register char *cp;
48*10898Sroland.mainz@nrubsig.org 	register double d=0;
498462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
50*10898Sroland.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 	{
57*10898Sroland.mainz@nrubsig.org 		case 's':
58*10898Sroland.mainz@nrubsig.org 			sflag=1;
59*10898Sroland.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;
68*10898Sroland.mainz@nrubsig.org 	if(cp = *argv)
69*10898Sroland.mainz@nrubsig.org 	{
70*10898Sroland.mainz@nrubsig.org 		d = strtod(cp, &last);
71*10898Sroland.mainz@nrubsig.org 		if(*last)
72*10898Sroland.mainz@nrubsig.org 		{
73*10898Sroland.mainz@nrubsig.org 			Time_t now,ns;
74*10898Sroland.mainz@nrubsig.org 			char* pp;
75*10898Sroland.mainz@nrubsig.org 			now = TMX_NOW;
76*10898Sroland.mainz@nrubsig.org 			if(*cp == 'P' || *cp == 'p')
77*10898Sroland.mainz@nrubsig.org 				ns = tmxdate(cp, &last, now);
78*10898Sroland.mainz@nrubsig.org 			else
79*10898Sroland.mainz@nrubsig.org 			{
80*10898Sroland.mainz@nrubsig.org 				if(pp = sfprints("exact %s", cp))
81*10898Sroland.mainz@nrubsig.org 					ns = tmxdate(pp, &last, now);
82*10898Sroland.mainz@nrubsig.org 				if(*last && (pp = sfprints("p%s", cp)))
83*10898Sroland.mainz@nrubsig.org 					ns = tmxdate(pp, &last, now);
84*10898Sroland.mainz@nrubsig.org 			}
85*10898Sroland.mainz@nrubsig.org 			if(*last)
86*10898Sroland.mainz@nrubsig.org 				errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
87*10898Sroland.mainz@nrubsig.org 			d = ns - now;
88*10898Sroland.mainz@nrubsig.org 			d /= TMX_RESOLUTION;
89*10898Sroland.mainz@nrubsig.org 		}
90*10898Sroland.mainz@nrubsig.org 		if(argv[1])
91*10898Sroland.mainz@nrubsig.org 			errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
92*10898Sroland.mainz@nrubsig.org 	}
93*10898Sroland.mainz@nrubsig.org 	else if(!sflag)
94*10898Sroland.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 	}
100*10898Sroland.mainz@nrubsig.org 	if(sflag && d==0)
101*10898Sroland.mainz@nrubsig.org 		pause();
102*10898Sroland.mainz@nrubsig.org 	else while(1)
1034887Schin 	{
1044887Schin 		time_t now;
1054887Schin 		errno = 0;
1064887Schin 		shp->lastsig=0;
1074887Schin 		sh_delay(d);
108*10898Sroland.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 
1204887Schin static void completed(void * handle)
1214887Schin {
1224887Schin 	char *expired = (char*)handle;
1234887Schin 	*expired = 1;
1244887Schin }
1254887Schin 
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 
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