diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
commit | 3950ffe2a485479f6561c27364d3d7df5a21d124 (patch) | |
tree | 468c6e14449d1b1e279222ec32f676b0311917d2 /src/cmd/ksh93/bltins/sleep.c | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/cmd/ksh93/bltins/sleep.c')
-rw-r--r-- | src/cmd/ksh93/bltins/sleep.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/cmd/ksh93/bltins/sleep.c b/src/cmd/ksh93/bltins/sleep.c new file mode 100644 index 0000000..ca9d055 --- /dev/null +++ b/src/cmd/ksh93/bltins/sleep.c @@ -0,0 +1,235 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1982-2012 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* David Korn <dgk@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * sleep delay + * + * David Korn + * AT&T Labs + * + */ + +#define sleep ______sleep +#include "defs.h" +#undef sleep +#include <error.h> +#include <errno.h> +#include <tmx.h> +#include "builtins.h" +#include "FEATURE/time" +#include "FEATURE/poll" +#ifdef _NEXT_SOURCE +# define sleep _ast_sleep +#endif /* _NEXT_SOURCE */ +#ifdef _lib_poll_notimer +# undef _lib_poll +#endif /* _lib_poll_notimer */ + +int b_sleep(register int argc,char *argv[],Shbltin_t *context) +{ + register char *cp; + register double d=0; + register Shell_t *shp = context->shp; + int sflag=0; + time_t tloc = 0; + char *last; + if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF))) + sh_sigtrap(SIGALRM); + while((argc = optget(argv,sh_optsleep))) switch(argc) + { + case 's': + sflag=1; + break; + case ':': + errormsg(SH_DICT,2, "%s", opt_info.arg); + break; + case '?': + errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); + break; + } + argv += opt_info.index; + if(cp = *argv) + { + d = strtod(cp, &last); + if(*last) + { + Time_t now,ns; + char* pp; + now = TMX_NOW; + if(*cp == 'P' || *cp == 'p') + ns = tmxdate(cp, &last, now); + else if(*last=='.' && shp->decomma && d==(unsigned long)d) + { + *(pp=last) = ','; + if(!strchr(cp,'.')) + d = strtod(cp,&last); + *pp = '.'; + if(*last==0) + goto skip; + } + else if(*last!='.' && *last!=',') + { + if(pp = sfprints("exact %s", cp)) + ns = tmxdate(pp, &last, now); + if(*last && (pp = sfprints("p%s", cp))) + ns = tmxdate(pp, &last, now); + } + if(*last) + errormsg(SH_DICT,ERROR_exit(1),e_number,*argv); + d = ns - now; + d /= TMX_RESOLUTION; + } +skip: + if(argv[1]) + errormsg(SH_DICT,ERROR_exit(1),e_oneoperand); + } + else if(!sflag) + errormsg(SH_DICT,ERROR_exit(1),e_oneoperand); + if(d > .10) + { + time(&tloc); + tloc += (time_t)(d+.5); + } + if(sflag && d==0) + pause(); + else while(1) + { + time_t now; + errno = 0; + shp->lastsig=0; + sh_delay(d); + if(sflag || tloc==0 || errno!=EINTR || shp->lastsig) + break; + sh_sigcheck(shp); + if(tloc < (now=time(NIL(time_t*)))) + break; + d = (double)(tloc-now); + if(shp->sigflag[SIGALRM]&SH_SIGTRAP) + sh_timetraps(shp); + } + return(0); +} + +static void completed(void * handle) +{ + char *expired = (char*)handle; + *expired = 1; +} + +unsigned int sleep(unsigned int sec) +{ + Shell_t *shp = sh_getinterp(); + pid_t newpid, curpid=getpid(); + void *tp; + char expired = 0; + shp->lastsig = 0; + tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); + do + { + if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,-1L,0)==0) + pause(); + if(shp->sigflag[SIGALRM]&SH_SIGTRAP) + sh_timetraps(shp); + if((newpid=getpid()) != curpid) + { + curpid = newpid; + shp->lastsig = 0; + shp->trapnote &= ~SH_SIGSET; + if(expired) + expired = 0; + else + timerdel(tp); + tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); + } + } + while(!expired && shp->lastsig==0); + if(!expired) + timerdel(tp); + sh_sigcheck(shp); + return(0); +} + +/* + * delay execution for time <t> + */ + +void sh_delay(double t) +{ + register int n = (int)t; + Shell_t *shp = sh_getinterp(); +#ifdef _lib_poll + struct pollfd fd; + if(t<=0) + return; + else if(n > 30) + { + sleep(n); + t -= n; + } + if(n=(int)(1000*t)) + { + if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,(long)n,0)==0) + poll(&fd,0,n); + } +#else +# if defined(_lib_select) && defined(_mem_tv_usec_timeval) + struct timeval timeloc; + if(t<=0) + return; + if(n=(int)(1000*t) && shp->gd->waitevent && (*shp->gd->waitevent)(-1,(long)n,0)) + return; + n = (int)t; + timeloc.tv_sec = n; + timeloc.tv_usec = 1000000*(t-(double)n); + select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc); +# else +# ifdef _lib_select + /* for 9th edition machines */ + if(t<=0) + return; + if(n > 30) + { + sleep(n); + t -= n; + } + if(n=(int)(1000*t)) + { + if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,(long)n,0)==0) + select(0,(fd_set*)0,(fd_set*)0,n); + } +# else + struct tms tt; + if(t<=0) + return; + sleep(n); + t -= n; + if(t) + { + clock_t begin = times(&tt); + if(begin==0) + return; + t *= shp->gd->lim.clk_tck; + n += (t+.5); + while((times(&tt)-begin) < n); + } +# endif +# endif +#endif /* _lib_poll */ +} |