1da2e3ebdSchin /***********************************************************************
25947648bSMarcel Telka  *                                                                      *
35947648bSMarcel Telka  *               This software is part of the ast package               *
45947648bSMarcel Telka  *          Copyright (c) 1982-2013 AT&T Intellectual Property          *
55947648bSMarcel Telka  *                      and is licensed under the                       *
65947648bSMarcel Telka  *                 Eclipse Public License, Version 1.0                  *
75947648bSMarcel Telka  *                    by AT&T Intellectual Property                     *
85947648bSMarcel Telka  *                                                                      *
95947648bSMarcel Telka  *                A copy of the License is available at                 *
105947648bSMarcel Telka  *          http://www.eclipse.org/org/documents/epl-v10.html           *
115947648bSMarcel Telka  *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
125947648bSMarcel Telka  *                                                                      *
135947648bSMarcel Telka  *              Information and Software Systems Research               *
145947648bSMarcel Telka  *                            AT&T Research                             *
155947648bSMarcel Telka  *                           Florham Park NJ                            *
165947648bSMarcel Telka  *                                                                      *
175947648bSMarcel Telka  *                    David Korn <dgkorn@gmail.com>                     *
185947648bSMarcel Telka  *                                                                      *
195947648bSMarcel Telka  ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /*
22da2e3ebdSchin  * sleep delay
23da2e3ebdSchin  *
24da2e3ebdSchin  *   David Korn
25da2e3ebdSchin  *   AT&T Labs
26da2e3ebdSchin  *
27da2e3ebdSchin  */
28da2e3ebdSchin 
29da2e3ebdSchin #define sleep	______sleep
30da2e3ebdSchin #include	"defs.h"
31da2e3ebdSchin #undef	sleep
32da2e3ebdSchin #include	<error.h>
33da2e3ebdSchin #include	<errno.h>
3434f9b3eeSRoland Mainz #include	<tmx.h>
35da2e3ebdSchin #include	"builtins.h"
36da2e3ebdSchin #include	"FEATURE/time"
37da2e3ebdSchin #include	"FEATURE/poll"
38da2e3ebdSchin #ifdef _NEXT_SOURCE
39da2e3ebdSchin #   define sleep	_ast_sleep
40da2e3ebdSchin #endif /* _NEXT_SOURCE */
41da2e3ebdSchin #ifdef _lib_poll_notimer
42da2e3ebdSchin #   undef _lib_poll
43da2e3ebdSchin #endif /* _lib_poll_notimer */
44da2e3ebdSchin 
b_sleep(register int argc,char * argv[],Shbltin_t * context)45*b30d1939SAndy Fiddaman int	b_sleep(register int argc,char *argv[],Shbltin_t *context)
46da2e3ebdSchin {
47da2e3ebdSchin 	register char *cp;
4834f9b3eeSRoland Mainz 	register double d=0;
49*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
5034f9b3eeSRoland Mainz 	int sflag=0;
51da2e3ebdSchin 	time_t tloc = 0;
527c2fbfb3SApril Chin 	char *last;
537c2fbfb3SApril Chin 	if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
547c2fbfb3SApril Chin 		sh_sigtrap(SIGALRM);
55da2e3ebdSchin 	while((argc = optget(argv,sh_optsleep))) switch(argc)
56da2e3ebdSchin 	{
5734f9b3eeSRoland Mainz 		case 's':
5834f9b3eeSRoland Mainz 			sflag=1;
5934f9b3eeSRoland Mainz 			break;
60da2e3ebdSchin 		case ':':
61da2e3ebdSchin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
62da2e3ebdSchin 			break;
63da2e3ebdSchin 		case '?':
64da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
65da2e3ebdSchin 			break;
66da2e3ebdSchin 	}
67da2e3ebdSchin 	argv += opt_info.index;
6834f9b3eeSRoland Mainz 	if(cp = *argv)
6934f9b3eeSRoland Mainz 	{
7034f9b3eeSRoland Mainz 		d = strtod(cp, &last);
7134f9b3eeSRoland Mainz 		if(*last)
7234f9b3eeSRoland Mainz 		{
7334f9b3eeSRoland Mainz 			Time_t now,ns;
7434f9b3eeSRoland Mainz 			char* pp;
7534f9b3eeSRoland Mainz 			now = TMX_NOW;
7634f9b3eeSRoland Mainz 			if(*cp == 'P' || *cp == 'p')
7734f9b3eeSRoland Mainz 				ns = tmxdate(cp, &last, now);
78*b30d1939SAndy Fiddaman 			else if(*last=='.' && shp->decomma && d==(unsigned long)d)
79*b30d1939SAndy Fiddaman 			{
80*b30d1939SAndy Fiddaman 				*(pp=last) = ',';
81*b30d1939SAndy Fiddaman 				if(!strchr(cp,'.'))
82*b30d1939SAndy Fiddaman 					d = strtod(cp,&last);
83*b30d1939SAndy Fiddaman 				*pp = '.';
84*b30d1939SAndy Fiddaman 				if(*last==0)
85*b30d1939SAndy Fiddaman 					goto skip;
86*b30d1939SAndy Fiddaman 			}
87*b30d1939SAndy Fiddaman 			else if(*last!='.' && *last!=',')
8834f9b3eeSRoland Mainz 			{
8934f9b3eeSRoland Mainz 				if(pp = sfprints("exact %s", cp))
9034f9b3eeSRoland Mainz 					ns = tmxdate(pp, &last, now);
9134f9b3eeSRoland Mainz 				if(*last && (pp = sfprints("p%s", cp)))
9234f9b3eeSRoland Mainz 					ns = tmxdate(pp, &last, now);
9334f9b3eeSRoland Mainz 			}
9434f9b3eeSRoland Mainz 			if(*last)
9534f9b3eeSRoland Mainz 				errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
9634f9b3eeSRoland Mainz 			d = ns - now;
9734f9b3eeSRoland Mainz 			d /= TMX_RESOLUTION;
9834f9b3eeSRoland Mainz 		}
99*b30d1939SAndy Fiddaman skip:
10034f9b3eeSRoland Mainz 		if(argv[1])
10134f9b3eeSRoland Mainz 			errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
10234f9b3eeSRoland Mainz 	}
10334f9b3eeSRoland Mainz 	else if(!sflag)
10434f9b3eeSRoland Mainz 		errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
1057c2fbfb3SApril Chin 	if(d > .10)
106da2e3ebdSchin 	{
107da2e3ebdSchin 		time(&tloc);
108da2e3ebdSchin 		tloc += (time_t)(d+.5);
109da2e3ebdSchin 	}
11034f9b3eeSRoland Mainz 	if(sflag && d==0)
11134f9b3eeSRoland Mainz 		pause();
11234f9b3eeSRoland Mainz 	else while(1)
113da2e3ebdSchin 	{
114da2e3ebdSchin 		time_t now;
115da2e3ebdSchin 		errno = 0;
116da2e3ebdSchin 		shp->lastsig=0;
117da2e3ebdSchin 		sh_delay(d);
11834f9b3eeSRoland Mainz 		if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
119da2e3ebdSchin 			break;
120*b30d1939SAndy Fiddaman 		sh_sigcheck(shp);
121da2e3ebdSchin 		if(tloc < (now=time(NIL(time_t*))))
122da2e3ebdSchin 			break;
123da2e3ebdSchin 		d = (double)(tloc-now);
124da2e3ebdSchin 		if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
125*b30d1939SAndy Fiddaman 			sh_timetraps(shp);
126da2e3ebdSchin 	}
127da2e3ebdSchin 	return(0);
128da2e3ebdSchin }
129da2e3ebdSchin 
completed(void * handle)130da2e3ebdSchin static void completed(void * handle)
131da2e3ebdSchin {
132da2e3ebdSchin 	char *expired = (char*)handle;
133da2e3ebdSchin 	*expired = 1;
134da2e3ebdSchin }
135da2e3ebdSchin 
sleep(unsigned int sec)136da2e3ebdSchin unsigned int sleep(unsigned int sec)
137da2e3ebdSchin {
138*b30d1939SAndy Fiddaman 	Shell_t	*shp = sh_getinterp();
139da2e3ebdSchin 	pid_t newpid, curpid=getpid();
140da2e3ebdSchin 	void *tp;
141da2e3ebdSchin 	char expired = 0;
1427c2fbfb3SApril Chin 	shp->lastsig = 0;
143da2e3ebdSchin 	tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
144da2e3ebdSchin 	do
145da2e3ebdSchin 	{
146*b30d1939SAndy Fiddaman 		if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,-1L,0)==0)
147da2e3ebdSchin 			pause();
1487c2fbfb3SApril Chin 		if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
149*b30d1939SAndy Fiddaman 			sh_timetraps(shp);
150da2e3ebdSchin 		if((newpid=getpid()) != curpid)
151da2e3ebdSchin 		{
152da2e3ebdSchin 			curpid = newpid;
1537c2fbfb3SApril Chin 			shp->lastsig = 0;
1547c2fbfb3SApril Chin 			shp->trapnote &= ~SH_SIGSET;
155da2e3ebdSchin 			if(expired)
156da2e3ebdSchin 				expired = 0;
157da2e3ebdSchin 			else
158da2e3ebdSchin 				timerdel(tp);
159da2e3ebdSchin 			tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
160da2e3ebdSchin 		}
161da2e3ebdSchin 	}
1627c2fbfb3SApril Chin 	while(!expired && shp->lastsig==0);
163da2e3ebdSchin 	if(!expired)
164da2e3ebdSchin 		timerdel(tp);
165*b30d1939SAndy Fiddaman 	sh_sigcheck(shp);
166da2e3ebdSchin 	return(0);
167da2e3ebdSchin }
168da2e3ebdSchin 
1695947648bSMarcel Telka //
1705947648bSMarcel Telka // Delay execution for time <t>.
1715947648bSMarcel Telka //
sh_delay(double t)1725947648bSMarcel Telka void sh_delay(double t) {
1735947648bSMarcel Telka     Shell_t *shp = sh_getinterp();
1745947648bSMarcel Telka     int n = (int)t;
1755947648bSMarcel Telka     Tv_t ts, tx;
176da2e3ebdSchin 
1775947648bSMarcel Telka     ts.tv_sec = n;
1785947648bSMarcel Telka     ts.tv_nsec = 1000000000 * (t - (double)n);
1795947648bSMarcel Telka     while (tvsleep(&ts, &tx) < 0 && errno == EINTR) {
1805947648bSMarcel Telka         if (shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) return;
1815947648bSMarcel Telka         ts = tx;
1825947648bSMarcel Telka     }
183*b30d1939SAndy Fiddaman  }
184