summaryrefslogtreecommitdiff
path: root/src/cmd/ksh93/bltins/sleep.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
commit3950ffe2a485479f6561c27364d3d7df5a21d124 (patch)
tree468c6e14449d1b1e279222ec32f676b0311917d2 /src/cmd/ksh93/bltins/sleep.c
downloadksh-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.c235
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 */
+}