14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*8462SApril.Chin@Sun.COM *          Copyright (c) 1982-2008 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
7*8462SApril.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>
344887Schin #include	"builtins.h"
354887Schin #include	"FEATURE/time"
364887Schin #include	"FEATURE/poll"
374887Schin #ifdef _NEXT_SOURCE
384887Schin #   define sleep	_ast_sleep
394887Schin #endif /* _NEXT_SOURCE */
404887Schin #ifdef _lib_poll_notimer
414887Schin #   undef _lib_poll
424887Schin #endif /* _lib_poll_notimer */
434887Schin 
444887Schin int	b_sleep(register int argc,char *argv[],void *extra)
454887Schin {
464887Schin 	register char *cp;
474887Schin 	register double d;
48*8462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
494887Schin 	time_t tloc = 0;
50*8462SApril.Chin@Sun.COM 	char *last;
51*8462SApril.Chin@Sun.COM 	if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
52*8462SApril.Chin@Sun.COM 		sh_sigtrap(SIGALRM);
534887Schin 	while((argc = optget(argv,sh_optsleep))) switch(argc)
544887Schin 	{
554887Schin 		case ':':
564887Schin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
574887Schin 			break;
584887Schin 		case '?':
594887Schin 			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
604887Schin 			break;
614887Schin 	}
624887Schin 	argv += opt_info.index;
63*8462SApril.Chin@Sun.COM 	if(error_info.errors || !(cp= *argv) || ((d=strtod(cp, (char**)&last)),*last))
644887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
65*8462SApril.Chin@Sun.COM 	if(d > .10)
664887Schin 	{
674887Schin 		time(&tloc);
684887Schin 		tloc += (time_t)(d+.5);
694887Schin 	}
704887Schin 	while(1)
714887Schin 	{
724887Schin 		time_t now;
734887Schin 		errno = 0;
744887Schin 		shp->lastsig=0;
754887Schin 		sh_delay(d);
764887Schin 		if(tloc==0 || errno!=EINTR || shp->lastsig)
774887Schin 			break;
784887Schin 		sh_sigcheck();
794887Schin 		if(tloc < (now=time(NIL(time_t*))))
804887Schin 			break;
814887Schin 		d = (double)(tloc-now);
824887Schin 		if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
834887Schin 			sh_timetraps();
844887Schin 	}
854887Schin 	return(0);
864887Schin }
874887Schin 
884887Schin static void completed(void * handle)
894887Schin {
904887Schin 	char *expired = (char*)handle;
914887Schin 	*expired = 1;
924887Schin }
934887Schin 
944887Schin unsigned int sleep(unsigned int sec)
954887Schin {
96*8462SApril.Chin@Sun.COM 	Shell_t	*shp = &sh;
974887Schin 	pid_t newpid, curpid=getpid();
984887Schin 	void *tp;
994887Schin 	char expired = 0;
100*8462SApril.Chin@Sun.COM 	shp->lastsig = 0;
1014887Schin 	tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
1024887Schin 	do
1034887Schin 	{
104*8462SApril.Chin@Sun.COM 		if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0)
1054887Schin 			pause();
106*8462SApril.Chin@Sun.COM 		if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
1074887Schin 			sh_timetraps();
1084887Schin 		if((newpid=getpid()) != curpid)
1094887Schin 		{
1104887Schin 			curpid = newpid;
111*8462SApril.Chin@Sun.COM 			shp->lastsig = 0;
112*8462SApril.Chin@Sun.COM 			shp->trapnote &= ~SH_SIGSET;
1134887Schin 			if(expired)
1144887Schin 				expired = 0;
1154887Schin 			else
1164887Schin 				timerdel(tp);
1174887Schin 			tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
1184887Schin 		}
1194887Schin 	}
120*8462SApril.Chin@Sun.COM 	while(!expired && shp->lastsig==0);
1214887Schin 	if(!expired)
1224887Schin 		timerdel(tp);
1234887Schin 	sh_sigcheck();
1244887Schin 	return(0);
1254887Schin }
1264887Schin 
1274887Schin /*
1284887Schin  * delay execution for time <t>
1294887Schin  */
1304887Schin 
1314887Schin void	sh_delay(double t)
1324887Schin {
1334887Schin 	register int n = (int)t;
134*8462SApril.Chin@Sun.COM 	Shell_t	*shp = &sh;
1354887Schin #ifdef _lib_poll
1364887Schin 	struct pollfd fd;
1374887Schin 	if(t<=0)
1384887Schin 		return;
1394887Schin 	else if(n > 30)
1404887Schin 	{
1414887Schin 		sleep(n);
1424887Schin 		t -= n;
1434887Schin 	}
1444887Schin 	if(n=(int)(1000*t))
1454887Schin 	{
146*8462SApril.Chin@Sun.COM 		if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
1474887Schin 			poll(&fd,0,n);
1484887Schin 	}
1494887Schin #else
1504887Schin #   if defined(_lib_select) && defined(_mem_tv_usec_timeval)
1514887Schin 	struct timeval timeloc;
1524887Schin 	if(t<=0)
1534887Schin 		return;
154*8462SApril.Chin@Sun.COM 	if(n=(int)(1000*t) && shp->waitevent && (*shp->waitevent)(-1,(long)n,0))
1554887Schin 		return;
1564887Schin 	n = (int)t;
1574887Schin 	timeloc.tv_sec = n;
1584887Schin 	timeloc.tv_usec = 1000000*(t-(double)n);
1594887Schin 	select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc);
1604887Schin #   else
1614887Schin #	ifdef _lib_select
1624887Schin 		/* for 9th edition machines */
1634887Schin 		if(t<=0)
1644887Schin 			return;
1654887Schin 		if(n > 30)
1664887Schin 		{
1674887Schin 			sleep(n);
1684887Schin 			t -= n;
1694887Schin 		}
1704887Schin 		if(n=(int)(1000*t))
1714887Schin 		{
172*8462SApril.Chin@Sun.COM 			if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
1734887Schin 				select(0,(fd_set*)0,(fd_set*)0,n);
1744887Schin 		}
1754887Schin #	else
1764887Schin 		struct tms tt;
1774887Schin 		if(t<=0)
1784887Schin 			return;
1794887Schin 		sleep(n);
1804887Schin 		t -= n;
1814887Schin 		if(t)
1824887Schin 		{
1834887Schin 			clock_t begin = times(&tt);
1844887Schin 			if(begin==0)
1854887Schin 				return;
186*8462SApril.Chin@Sun.COM 			t *= shp->lim.clk_tck;
1874887Schin 			n += (t+.5);
1884887Schin 			while((times(&tt)-begin) < n);
1894887Schin 		}
1904887Schin #	endif
1914887Schin #   endif
1924887Schin #endif /* _lib_poll */
1934887Schin }
194