1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1982-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * David Korn <dgk@research.att.com> * 18*4887Schin * * 19*4887Schin ***********************************************************************/ 20*4887Schin #pragma prototyped 21*4887Schin /* 22*4887Schin * sleep delay 23*4887Schin * 24*4887Schin * David Korn 25*4887Schin * AT&T Labs 26*4887Schin * research!dgk 27*4887Schin * 28*4887Schin */ 29*4887Schin 30*4887Schin #define sleep ______sleep 31*4887Schin #include "defs.h" 32*4887Schin #undef sleep 33*4887Schin #include <error.h> 34*4887Schin #include <errno.h> 35*4887Schin #include "builtins.h" 36*4887Schin #include "FEATURE/time" 37*4887Schin #include "FEATURE/poll" 38*4887Schin #ifdef _NEXT_SOURCE 39*4887Schin # define sleep _ast_sleep 40*4887Schin #endif /* _NEXT_SOURCE */ 41*4887Schin #ifdef _lib_poll_notimer 42*4887Schin # undef _lib_poll 43*4887Schin #endif /* _lib_poll_notimer */ 44*4887Schin 45*4887Schin int b_sleep(register int argc,char *argv[],void *extra) 46*4887Schin { 47*4887Schin register char *cp; 48*4887Schin register double d; 49*4887Schin register Shell_t *shp = (Shell_t*)extra; 50*4887Schin time_t tloc = 0; 51*4887Schin while((argc = optget(argv,sh_optsleep))) switch(argc) 52*4887Schin { 53*4887Schin case ':': 54*4887Schin errormsg(SH_DICT,2, "%s", opt_info.arg); 55*4887Schin break; 56*4887Schin case '?': 57*4887Schin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); 58*4887Schin break; 59*4887Schin } 60*4887Schin argv += opt_info.index; 61*4887Schin if(error_info.errors || !(cp= *argv) || !(strmatch(cp,e_numeric))) 62*4887Schin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); 63*4887Schin if((d=strtod(cp, (char**)0)) > .10) 64*4887Schin { 65*4887Schin sfsync(shp->outpool); 66*4887Schin time(&tloc); 67*4887Schin tloc += (time_t)(d+.5); 68*4887Schin } 69*4887Schin while(1) 70*4887Schin { 71*4887Schin time_t now; 72*4887Schin errno = 0; 73*4887Schin shp->lastsig=0; 74*4887Schin sh_delay(d); 75*4887Schin if(tloc==0 || errno!=EINTR || shp->lastsig) 76*4887Schin break; 77*4887Schin sh_sigcheck(); 78*4887Schin if(tloc < (now=time(NIL(time_t*)))) 79*4887Schin break; 80*4887Schin d = (double)(tloc-now); 81*4887Schin if(shp->sigflag[SIGALRM]&SH_SIGTRAP) 82*4887Schin sh_timetraps(); 83*4887Schin } 84*4887Schin return(0); 85*4887Schin } 86*4887Schin 87*4887Schin static void completed(void * handle) 88*4887Schin { 89*4887Schin char *expired = (char*)handle; 90*4887Schin *expired = 1; 91*4887Schin } 92*4887Schin 93*4887Schin unsigned int sleep(unsigned int sec) 94*4887Schin { 95*4887Schin pid_t newpid, curpid=getpid(); 96*4887Schin void *tp; 97*4887Schin char expired = 0; 98*4887Schin sh.lastsig = 0; 99*4887Schin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 100*4887Schin do 101*4887Schin { 102*4887Schin if(!sh.waitevent || (*sh.waitevent)(-1,-1L,0)==0) 103*4887Schin pause(); 104*4887Schin if(sh.sigflag[SIGALRM]&SH_SIGTRAP) 105*4887Schin sh_timetraps(); 106*4887Schin if((newpid=getpid()) != curpid) 107*4887Schin { 108*4887Schin curpid = newpid; 109*4887Schin sh.lastsig = 0; 110*4887Schin sh.trapnote &= ~SH_SIGSET; 111*4887Schin if(expired) 112*4887Schin expired = 0; 113*4887Schin else 114*4887Schin timerdel(tp); 115*4887Schin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 116*4887Schin } 117*4887Schin } 118*4887Schin while(!expired && sh.lastsig==0); 119*4887Schin if(!expired) 120*4887Schin timerdel(tp); 121*4887Schin sh_sigcheck(); 122*4887Schin return(0); 123*4887Schin } 124*4887Schin 125*4887Schin /* 126*4887Schin * delay execution for time <t> 127*4887Schin */ 128*4887Schin 129*4887Schin void sh_delay(double t) 130*4887Schin { 131*4887Schin register int n = (int)t; 132*4887Schin #ifdef _lib_poll 133*4887Schin struct pollfd fd; 134*4887Schin if(t<=0) 135*4887Schin return; 136*4887Schin else if(n > 30) 137*4887Schin { 138*4887Schin sleep(n); 139*4887Schin t -= n; 140*4887Schin } 141*4887Schin if(n=(int)(1000*t)) 142*4887Schin { 143*4887Schin if(!sh.waitevent || (*sh.waitevent)(-1,(long)n,0)==0) 144*4887Schin poll(&fd,0,n); 145*4887Schin } 146*4887Schin #else 147*4887Schin # if defined(_lib_select) && defined(_mem_tv_usec_timeval) 148*4887Schin struct timeval timeloc; 149*4887Schin if(t<=0) 150*4887Schin return; 151*4887Schin if(n=(int)(1000*t) && sh.waitevent && (*sh.waitevent)(-1,(long)n,0)) 152*4887Schin return; 153*4887Schin n = (int)t; 154*4887Schin timeloc.tv_sec = n; 155*4887Schin timeloc.tv_usec = 1000000*(t-(double)n); 156*4887Schin select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc); 157*4887Schin # else 158*4887Schin # ifdef _lib_select 159*4887Schin /* for 9th edition machines */ 160*4887Schin if(t<=0) 161*4887Schin return; 162*4887Schin if(n > 30) 163*4887Schin { 164*4887Schin sleep(n); 165*4887Schin t -= n; 166*4887Schin } 167*4887Schin if(n=(int)(1000*t)) 168*4887Schin { 169*4887Schin if(!sh.waitevent || (*sh.waitevent)(-1,(long)n,0)==0) 170*4887Schin select(0,(fd_set*)0,(fd_set*)0,n); 171*4887Schin } 172*4887Schin # else 173*4887Schin struct tms tt; 174*4887Schin if(t<=0) 175*4887Schin return; 176*4887Schin sleep(n); 177*4887Schin t -= n; 178*4887Schin if(t) 179*4887Schin { 180*4887Schin clock_t begin = times(&tt); 181*4887Schin if(begin==0) 182*4887Schin return; 183*4887Schin t *= sh.lim.clk_tck; 184*4887Schin n += (t+.5); 185*4887Schin while((times(&tt)-begin) < n); 186*4887Schin } 187*4887Schin # endif 188*4887Schin # endif 189*4887Schin #endif /* _lib_poll */ 190*4887Schin } 191