da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * sleep delay
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define sleep ______sleep
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef sleep
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <errno.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <tmx.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/time"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/poll"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _NEXT_SOURCE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define sleep _ast_sleep
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _NEXT_SOURCE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _lib_poll_notimer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# undef _lib_poll
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_poll_notimer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint b_sleep(register int argc,char *argv[],void *extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register double d=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int sflag=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin time_t tloc = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *last;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_sigtrap(SIGALRM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((argc = optget(argv,sh_optsleep))) switch(argc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 's':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sflag=1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(cp = *argv)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz d = strtod(cp, &last);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*last)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Time_t now,ns;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* pp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz now = TMX_NOW;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*cp == 'P' || *cp == 'p')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ns = tmxdate(cp, &last, now);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(pp = sfprints("exact %s", cp))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ns = tmxdate(pp, &last, now);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*last && (pp = sfprints("p%s", cp)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ns = tmxdate(pp, &last, now);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*last)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_exit(1),e_number,*argv);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz d = ns - now;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz d /= TMX_RESOLUTION;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(argv[1])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(!sflag)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_exit(1),e_oneoperand);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(d > .10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin time(&tloc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tloc += (time_t)(d+.5);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sflag && d==0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pause();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin time_t now;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->lastsig=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_delay(d);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tloc < (now=time(NIL(time_t*))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = (double)(tloc-now);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_timetraps();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void completed(void * handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *expired = (char*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *expired = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinunsigned int sleep(unsigned int sec)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t newpid, curpid=getpid();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char expired = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastsig = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pause();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_timetraps();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((newpid=getpid()) != curpid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin curpid = newpid;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastsig = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote &= ~SH_SIGSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(expired)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin expired = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timerdel(tp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(!expired && shp->lastsig==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!expired)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timerdel(tp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigcheck();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * delay execution for time <t>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_delay(double t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n = (int)t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef _lib_poll
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pollfd fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n > 30)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sleep(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=(int)(1000*t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin poll(&fd,0,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(_lib_select) && defined(_mem_tv_usec_timeval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct timeval timeloc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n=(int)(1000*t) && shp->waitevent && (*shp->waitevent)(-1,(long)n,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (int)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeloc.tv_sec = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeloc.tv_usec = 1000000*(t-(double)n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef _lib_select
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* for 9th edition machines */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n > 30)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sleep(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=(int)(1000*t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin select(0,(fd_set*)0,(fd_set*)0,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct tms tt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sleep(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clock_t begin = times(&tt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(begin==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t *= shp->lim.clk_tck;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n += (t+.5);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((times(&tt)-begin) < n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_poll */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}