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