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