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