sleep.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2007 AT&T Knowledge Ventures *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Knowledge Ventures *
* *
* A copy of the License is available at *
* http://www.opensource.org/licenses/cpl1.0.txt *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* 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
* research!dgk
*
*/
#define sleep ______sleep
#include "defs.h"
#undef sleep
#include <error.h>
#include <errno.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[],void *extra)
{
register char *cp;
register double d;
register Shell_t *shp = (Shell_t*)extra;
time_t tloc = 0;
while((argc = optget(argv,sh_optsleep))) switch(argc)
{
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(error_info.errors || !(cp= *argv) || !(strmatch(cp,e_numeric)))
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
if((d=strtod(cp, (char**)0)) > .10)
{
sfsync(shp->outpool);
time(&tloc);
tloc += (time_t)(d+.5);
}
while(1)
{
time_t now;
errno = 0;
shp->lastsig=0;
sh_delay(d);
if(tloc==0 || errno!=EINTR || shp->lastsig)
break;
sh_sigcheck();
if(tloc < (now=time(NIL(time_t*))))
break;
d = (double)(tloc-now);
if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
sh_timetraps();
}
return(0);
}
static void completed(void * handle)
{
char *expired = (char*)handle;
*expired = 1;
}
unsigned int sleep(unsigned int sec)
{
pid_t newpid, curpid=getpid();
void *tp;
char expired = 0;
sh.lastsig = 0;
tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
do
{
if(!sh.waitevent || (*sh.waitevent)(-1,-1L,0)==0)
pause();
if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
sh_timetraps();
if((newpid=getpid()) != curpid)
{
curpid = newpid;
sh.lastsig = 0;
sh.trapnote &= ~SH_SIGSET;
if(expired)
expired = 0;
else
timerdel(tp);
tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired);
}
}
while(!expired && sh.lastsig==0);
if(!expired)
timerdel(tp);
sh_sigcheck();
return(0);
}
/*
* delay execution for time <t>
*/
void sh_delay(double t)
{
register int n = (int)t;
#ifdef _lib_poll
struct pollfd fd;
if(t<=0)
return;
else if(n > 30)
{
sleep(n);
t -= n;
}
if(n=(int)(1000*t))
{
if(!sh.waitevent || (*sh.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) && sh.waitevent && (*sh.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(!sh.waitevent || (*sh.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 *= sh.lim.clk_tck;
n += (t+.5);
while((times(&tt)-begin) < n);
}
# endif
# endif
#endif /* _lib_poll */
}