xref: /titanic_51/usr/src/lib/libshell/common/bltins/sleep.c (revision 2777f608ce96fd0d3b91accea29d21d6aacbe7e5)
1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin  *                                                                      *
3da2e3ebdSchin  *               This software is part of the ast package               *
4*2777f608SMarcel Telka  *          Copyright (c) 1982-2013 AT&T Intellectual Property          *
5da2e3ebdSchin  *                      and is licensed under the                       *
6*2777f608SMarcel Telka  *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin  *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin  *                                                                      *
9da2e3ebdSchin  *                A copy of the License is available at                 *
10*2777f608SMarcel Telka  *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*2777f608SMarcel Telka  *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12da2e3ebdSchin  *                                                                      *
13da2e3ebdSchin  *              Information and Software Systems Research               *
14da2e3ebdSchin  *                            AT&T Research                             *
15da2e3ebdSchin  *                           Florham Park NJ                            *
16da2e3ebdSchin  *                                                                      *
17*2777f608SMarcel Telka  *                    David Korn <dgkorn@gmail.com>                     *
18da2e3ebdSchin  *                                                                      *
19da2e3ebdSchin  ***********************************************************************/
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[],void * extra)45da2e3ebdSchin int	b_sleep(register int argc,char *argv[],void *extra)
46da2e3ebdSchin {
47da2e3ebdSchin 	register char *cp;
4834f9b3eeSRoland Mainz 	register double d=0;
497c2fbfb3SApril Chin 	register Shell_t *shp = ((Shbltin_t*)extra)->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);
7834f9b3eeSRoland Mainz 			else
7934f9b3eeSRoland Mainz 			{
8034f9b3eeSRoland Mainz 				if(pp = sfprints("exact %s", cp))
8134f9b3eeSRoland Mainz 					ns = tmxdate(pp, &last, now);
8234f9b3eeSRoland Mainz 				if(*last && (pp = sfprints("p%s", cp)))
8334f9b3eeSRoland Mainz 					ns = tmxdate(pp, &last, now);
8434f9b3eeSRoland Mainz 			}
8534f9b3eeSRoland Mainz 			if(*last)
8634f9b3eeSRoland Mainz 				errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
8734f9b3eeSRoland Mainz 			d = ns - now;
8834f9b3eeSRoland Mainz 			d /= TMX_RESOLUTION;
8934f9b3eeSRoland Mainz 		}
9034f9b3eeSRoland Mainz 		if(argv[1])
9134f9b3eeSRoland Mainz 			errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
9234f9b3eeSRoland Mainz 	}
9334f9b3eeSRoland Mainz 	else if(!sflag)
9434f9b3eeSRoland Mainz 		errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
957c2fbfb3SApril Chin 	if(d > .10)
96da2e3ebdSchin 	{
97da2e3ebdSchin 		time(&tloc);
98da2e3ebdSchin 		tloc += (time_t)(d+.5);
99da2e3ebdSchin 	}
10034f9b3eeSRoland Mainz 	if(sflag && d==0)
10134f9b3eeSRoland Mainz 		pause();
10234f9b3eeSRoland Mainz 	else while(1)
103da2e3ebdSchin 	{
104da2e3ebdSchin 		time_t now;
105da2e3ebdSchin 		errno = 0;
106da2e3ebdSchin 		shp->lastsig=0;
107da2e3ebdSchin 		sh_delay(d);
10834f9b3eeSRoland Mainz 		if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
109da2e3ebdSchin 			break;
110da2e3ebdSchin 		sh_sigcheck();
111da2e3ebdSchin 		if(tloc < (now=time(NIL(time_t*))))
112da2e3ebdSchin 			break;
113da2e3ebdSchin 		d = (double)(tloc-now);
114da2e3ebdSchin 		if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
115da2e3ebdSchin 			sh_timetraps();
116da2e3ebdSchin 	}
117da2e3ebdSchin 	return(0);
118da2e3ebdSchin }
119da2e3ebdSchin 
completed(void * handle)120da2e3ebdSchin static void completed(void * handle)
121da2e3ebdSchin {
122da2e3ebdSchin 	char *expired = (char*)handle;
123da2e3ebdSchin 	*expired = 1;
124da2e3ebdSchin }
125da2e3ebdSchin 
sleep(unsigned int sec)126da2e3ebdSchin unsigned int sleep(unsigned int sec)
127da2e3ebdSchin {
1287c2fbfb3SApril Chin 	Shell_t	*shp = &sh;
129da2e3ebdSchin 	pid_t newpid, curpid=getpid();
130da2e3ebdSchin 	void *tp;
131da2e3ebdSchin 	char expired = 0;
1327c2fbfb3SApril Chin 	shp->lastsig = 0;
133da2e3ebdSchin 	tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
134da2e3ebdSchin 	do
135da2e3ebdSchin 	{
1367c2fbfb3SApril Chin 		if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0)
137da2e3ebdSchin 			pause();
1387c2fbfb3SApril Chin 		if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
139da2e3ebdSchin 			sh_timetraps();
140da2e3ebdSchin 		if((newpid=getpid()) != curpid)
141da2e3ebdSchin 		{
142da2e3ebdSchin 			curpid = newpid;
1437c2fbfb3SApril Chin 			shp->lastsig = 0;
1447c2fbfb3SApril Chin 			shp->trapnote &= ~SH_SIGSET;
145da2e3ebdSchin 			if(expired)
146da2e3ebdSchin 				expired = 0;
147da2e3ebdSchin 			else
148da2e3ebdSchin 				timerdel(tp);
149da2e3ebdSchin 			tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
150da2e3ebdSchin 		}
151da2e3ebdSchin 	}
1527c2fbfb3SApril Chin 	while(!expired && shp->lastsig==0);
153da2e3ebdSchin 	if(!expired)
154da2e3ebdSchin 		timerdel(tp);
155da2e3ebdSchin 	sh_sigcheck();
156da2e3ebdSchin 	return(0);
157da2e3ebdSchin }
158da2e3ebdSchin 
159*2777f608SMarcel Telka //
160*2777f608SMarcel Telka // Delay execution for time <t>.
161*2777f608SMarcel Telka //
sh_delay(double t)162*2777f608SMarcel Telka void sh_delay(double t) {
163*2777f608SMarcel Telka     Shell_t *shp = sh_getinterp();
164*2777f608SMarcel Telka     int n = (int)t;
165*2777f608SMarcel Telka     Tv_t ts, tx;
166da2e3ebdSchin 
167*2777f608SMarcel Telka     ts.tv_sec = n;
168*2777f608SMarcel Telka     ts.tv_nsec = 1000000000 * (t - (double)n);
169*2777f608SMarcel Telka     while (tvsleep(&ts, &tx) < 0 && errno == EINTR) {
170*2777f608SMarcel Telka         if (shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) return;
171*2777f608SMarcel Telka         ts = tx;
172da2e3ebdSchin     }
173da2e3ebdSchin }
174