1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1982-2011 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 <tmx.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 45int b_sleep(register int argc,char *argv[],void *extra) 46{ 47 register char *cp; 48 register double d=0; 49 register Shell_t *shp = ((Shbltin_t*)extra)->shp; 50 int sflag=0; 51 time_t tloc = 0; 52 char *last; 53 if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF))) 54 sh_sigtrap(SIGALRM); 55 while((argc = optget(argv,sh_optsleep))) switch(argc) 56 { 57 case 's': 58 sflag=1; 59 break; 60 case ':': 61 errormsg(SH_DICT,2, "%s", opt_info.arg); 62 break; 63 case '?': 64 errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); 65 break; 66 } 67 argv += opt_info.index; 68 if(cp = *argv) 69 { 70 d = strtod(cp, &last); 71 if(*last) 72 { 73 Time_t now,ns; 74 char* pp; 75 now = TMX_NOW; 76 if(*cp == 'P' || *cp == 'p') 77 ns = tmxdate(cp, &last, now); 78 else if(*last=='.' && shp->decomma && d==(unsigned long)d) 79 { 80 *(pp=last) = ','; 81 if(!strchr(cp,'.')) 82 d = strtod(cp,&last); 83 *pp = '.'; 84 if(*last==0) 85 goto skip; 86 } 87 else if(*last!='.' && *last!=',') 88 { 89 if(pp = sfprints("exact %s", cp)) 90 ns = tmxdate(pp, &last, now); 91 if(*last && (pp = sfprints("p%s", cp))) 92 ns = tmxdate(pp, &last, now); 93 } 94 if(*last) 95 errormsg(SH_DICT,ERROR_exit(1),e_number,*argv); 96 d = ns - now; 97 d /= TMX_RESOLUTION; 98 } 99skip: 100 if(argv[1]) 101 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand); 102 } 103 else if(!sflag) 104 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand); 105 if(d > .10) 106 { 107 time(&tloc); 108 tloc += (time_t)(d+.5); 109 } 110 if(sflag && d==0) 111 pause(); 112 else while(1) 113 { 114 time_t now; 115 errno = 0; 116 shp->lastsig=0; 117 sh_delay(d); 118 if(sflag || tloc==0 || errno!=EINTR || shp->lastsig) 119 break; 120 sh_sigcheck(shp); 121 if(tloc < (now=time(NIL(time_t*)))) 122 break; 123 d = (double)(tloc-now); 124 if(shp->sigflag[SIGALRM]&SH_SIGTRAP) 125 sh_timetraps(shp); 126 } 127 return(0); 128} 129 130static void completed(void * handle) 131{ 132 char *expired = (char*)handle; 133 *expired = 1; 134} 135 136unsigned int sleep(unsigned int sec) 137{ 138 Shell_t *shp = sh_getinterp(); 139 pid_t newpid, curpid=getpid(); 140 void *tp; 141 char expired = 0; 142 shp->lastsig = 0; 143 tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 144 do 145 { 146 if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,-1L,0)==0) 147 pause(); 148 if(shp->sigflag[SIGALRM]&SH_SIGTRAP) 149 sh_timetraps(shp); 150 if((newpid=getpid()) != curpid) 151 { 152 curpid = newpid; 153 shp->lastsig = 0; 154 shp->trapnote &= ~SH_SIGSET; 155 if(expired) 156 expired = 0; 157 else 158 timerdel(tp); 159 tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 160 } 161 } 162 while(!expired && shp->lastsig==0); 163 if(!expired) 164 timerdel(tp); 165 sh_sigcheck(shp); 166 return(0); 167} 168 169/* 170 * delay execution for time <t> 171 */ 172 173void sh_delay(double t) 174{ 175 register int n = (int)t; 176 Shell_t *shp = sh_getinterp(); 177#ifdef _lib_poll 178 struct pollfd fd; 179 if(t<=0) 180 return; 181 else if(n > 30) 182 { 183 sleep(n); 184 t -= n; 185 } 186 if(n=(int)(1000*t)) 187 { 188 if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,(long)n,0)==0) 189 poll(&fd,0,n); 190 } 191#else 192# if defined(_lib_select) && defined(_mem_tv_usec_timeval) 193 struct timeval timeloc; 194 if(t<=0) 195 return; 196 if(n=(int)(1000*t) && shp->gd->waitevent && (*shp->gd->waitevent)(-1,(long)n,0)) 197 return; 198 n = (int)t; 199 timeloc.tv_sec = n; 200 timeloc.tv_usec = 1000000*(t-(double)n); 201 select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc); 202# else 203# ifdef _lib_select 204 /* for 9th edition machines */ 205 if(t<=0) 206 return; 207 if(n > 30) 208 { 209 sleep(n); 210 t -= n; 211 } 212 if(n=(int)(1000*t)) 213 { 214 if(!shp->gd->waitevent || (*shp->gd->waitevent)(-1,(long)n,0)==0) 215 select(0,(fd_set*)0,(fd_set*)0,n); 216 } 217# else 218 struct tms tt; 219 if(t<=0) 220 return; 221 sleep(n); 222 t -= n; 223 if(t) 224 { 225 clock_t begin = times(&tt); 226 if(begin==0) 227 return; 228 t *= shp->gd->lim.clk_tck; 229 n += (t+.5); 230 while((times(&tt)-begin) < n); 231 } 232# endif 233# endif 234#endif /* _lib_poll */ 235} 236