1*4887Schin /***********************************************************************
2*4887Schin *                                                                      *
3*4887Schin *               This software is part of the ast package               *
4*4887Schin *           Copyright (c) 1982-2007 AT&T Knowledge Ventures            *
5*4887Schin *                      and is licensed under the                       *
6*4887Schin *                  Common Public License, Version 1.0                  *
7*4887Schin *                      by AT&T Knowledge Ventures                      *
8*4887Schin *                                                                      *
9*4887Schin *                A copy of the License is available at                 *
10*4887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*4887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*4887Schin *                                                                      *
13*4887Schin *              Information and Software Systems Research               *
14*4887Schin *                            AT&T Research                             *
15*4887Schin *                           Florham Park NJ                            *
16*4887Schin *                                                                      *
17*4887Schin *                  David Korn <dgk@research.att.com>                   *
18*4887Schin *                                                                      *
19*4887Schin ***********************************************************************/
20*4887Schin #pragma prototyped
21*4887Schin /*
22*4887Schin  * sleep delay
23*4887Schin  *
24*4887Schin  *   David Korn
25*4887Schin  *   AT&T Labs
26*4887Schin  *   research!dgk
27*4887Schin  *
28*4887Schin  */
29*4887Schin 
30*4887Schin #define sleep	______sleep
31*4887Schin #include	"defs.h"
32*4887Schin #undef	sleep
33*4887Schin #include	<error.h>
34*4887Schin #include	<errno.h>
35*4887Schin #include	"builtins.h"
36*4887Schin #include	"FEATURE/time"
37*4887Schin #include	"FEATURE/poll"
38*4887Schin #ifdef _NEXT_SOURCE
39*4887Schin #   define sleep	_ast_sleep
40*4887Schin #endif /* _NEXT_SOURCE */
41*4887Schin #ifdef _lib_poll_notimer
42*4887Schin #   undef _lib_poll
43*4887Schin #endif /* _lib_poll_notimer */
44*4887Schin 
45*4887Schin int	b_sleep(register int argc,char *argv[],void *extra)
46*4887Schin {
47*4887Schin 	register char *cp;
48*4887Schin 	register double d;
49*4887Schin 	register Shell_t *shp = (Shell_t*)extra;
50*4887Schin 	time_t tloc = 0;
51*4887Schin 	while((argc = optget(argv,sh_optsleep))) switch(argc)
52*4887Schin 	{
53*4887Schin 		case ':':
54*4887Schin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
55*4887Schin 			break;
56*4887Schin 		case '?':
57*4887Schin 			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
58*4887Schin 			break;
59*4887Schin 	}
60*4887Schin 	argv += opt_info.index;
61*4887Schin 	if(error_info.errors || !(cp= *argv) || !(strmatch(cp,e_numeric)))
62*4887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
63*4887Schin 	if((d=strtod(cp, (char**)0)) > .10)
64*4887Schin 	{
65*4887Schin 		sfsync(shp->outpool);
66*4887Schin 		time(&tloc);
67*4887Schin 		tloc += (time_t)(d+.5);
68*4887Schin 	}
69*4887Schin 	while(1)
70*4887Schin 	{
71*4887Schin 		time_t now;
72*4887Schin 		errno = 0;
73*4887Schin 		shp->lastsig=0;
74*4887Schin 		sh_delay(d);
75*4887Schin 		if(tloc==0 || errno!=EINTR || shp->lastsig)
76*4887Schin 			break;
77*4887Schin 		sh_sigcheck();
78*4887Schin 		if(tloc < (now=time(NIL(time_t*))))
79*4887Schin 			break;
80*4887Schin 		d = (double)(tloc-now);
81*4887Schin 		if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
82*4887Schin 			sh_timetraps();
83*4887Schin 	}
84*4887Schin 	return(0);
85*4887Schin }
86*4887Schin 
87*4887Schin static void completed(void * handle)
88*4887Schin {
89*4887Schin 	char *expired = (char*)handle;
90*4887Schin 	*expired = 1;
91*4887Schin }
92*4887Schin 
93*4887Schin unsigned int sleep(unsigned int sec)
94*4887Schin {
95*4887Schin 	pid_t newpid, curpid=getpid();
96*4887Schin 	void *tp;
97*4887Schin 	char expired = 0;
98*4887Schin 	sh.lastsig = 0;
99*4887Schin 	tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
100*4887Schin 	do
101*4887Schin 	{
102*4887Schin 		if(!sh.waitevent || (*sh.waitevent)(-1,-1L,0)==0)
103*4887Schin 			pause();
104*4887Schin 		if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
105*4887Schin 			sh_timetraps();
106*4887Schin 		if((newpid=getpid()) != curpid)
107*4887Schin 		{
108*4887Schin 			curpid = newpid;
109*4887Schin 			sh.lastsig = 0;
110*4887Schin 			sh.trapnote &= ~SH_SIGSET;
111*4887Schin 			if(expired)
112*4887Schin 				expired = 0;
113*4887Schin 			else
114*4887Schin 				timerdel(tp);
115*4887Schin 			tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
116*4887Schin 		}
117*4887Schin 	}
118*4887Schin 	while(!expired && sh.lastsig==0);
119*4887Schin 	if(!expired)
120*4887Schin 		timerdel(tp);
121*4887Schin 	sh_sigcheck();
122*4887Schin 	return(0);
123*4887Schin }
124*4887Schin 
125*4887Schin /*
126*4887Schin  * delay execution for time <t>
127*4887Schin  */
128*4887Schin 
129*4887Schin void	sh_delay(double t)
130*4887Schin {
131*4887Schin 	register int n = (int)t;
132*4887Schin #ifdef _lib_poll
133*4887Schin 	struct pollfd fd;
134*4887Schin 	if(t<=0)
135*4887Schin 		return;
136*4887Schin 	else if(n > 30)
137*4887Schin 	{
138*4887Schin 		sleep(n);
139*4887Schin 		t -= n;
140*4887Schin 	}
141*4887Schin 	if(n=(int)(1000*t))
142*4887Schin 	{
143*4887Schin 		if(!sh.waitevent || (*sh.waitevent)(-1,(long)n,0)==0)
144*4887Schin 			poll(&fd,0,n);
145*4887Schin 	}
146*4887Schin #else
147*4887Schin #   if defined(_lib_select) && defined(_mem_tv_usec_timeval)
148*4887Schin 	struct timeval timeloc;
149*4887Schin 	if(t<=0)
150*4887Schin 		return;
151*4887Schin 	if(n=(int)(1000*t) && sh.waitevent && (*sh.waitevent)(-1,(long)n,0))
152*4887Schin 		return;
153*4887Schin 	n = (int)t;
154*4887Schin 	timeloc.tv_sec = n;
155*4887Schin 	timeloc.tv_usec = 1000000*(t-(double)n);
156*4887Schin 	select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc);
157*4887Schin #   else
158*4887Schin #	ifdef _lib_select
159*4887Schin 		/* for 9th edition machines */
160*4887Schin 		if(t<=0)
161*4887Schin 			return;
162*4887Schin 		if(n > 30)
163*4887Schin 		{
164*4887Schin 			sleep(n);
165*4887Schin 			t -= n;
166*4887Schin 		}
167*4887Schin 		if(n=(int)(1000*t))
168*4887Schin 		{
169*4887Schin 			if(!sh.waitevent || (*sh.waitevent)(-1,(long)n,0)==0)
170*4887Schin 				select(0,(fd_set*)0,(fd_set*)0,n);
171*4887Schin 		}
172*4887Schin #	else
173*4887Schin 		struct tms tt;
174*4887Schin 		if(t<=0)
175*4887Schin 			return;
176*4887Schin 		sleep(n);
177*4887Schin 		t -= n;
178*4887Schin 		if(t)
179*4887Schin 		{
180*4887Schin 			clock_t begin = times(&tt);
181*4887Schin 			if(begin==0)
182*4887Schin 				return;
183*4887Schin 			t *= sh.lim.clk_tck;
184*4887Schin 			n += (t+.5);
185*4887Schin 			while((times(&tt)-begin) < n);
186*4887Schin 		}
187*4887Schin #	endif
188*4887Schin #   endif
189*4887Schin #endif /* _lib_poll */
190*4887Schin }
191