xref: /onnv-gate/usr/src/lib/libshell/common/bltins/sleep.c (revision 12068:08a39a083754)
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