1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1982-2013 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * David Korn <dgkorn@gmail.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 45 int 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 79 { 80 if(pp = sfprints("exact %s", cp)) 81 ns = tmxdate(pp, &last, now); 82 if(*last && (pp = sfprints("p%s", cp))) 83 ns = tmxdate(pp, &last, now); 84 } 85 if(*last) 86 errormsg(SH_DICT,ERROR_exit(1),e_number,*argv); 87 d = ns - now; 88 d /= TMX_RESOLUTION; 89 } 90 if(argv[1]) 91 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand); 92 } 93 else if(!sflag) 94 errormsg(SH_DICT,ERROR_exit(1),e_oneoperand); 95 if(d > .10) 96 { 97 time(&tloc); 98 tloc += (time_t)(d+.5); 99 } 100 if(sflag && d==0) 101 pause(); 102 else while(1) 103 { 104 time_t now; 105 errno = 0; 106 shp->lastsig=0; 107 sh_delay(d); 108 if(sflag || tloc==0 || errno!=EINTR || shp->lastsig) 109 break; 110 sh_sigcheck(); 111 if(tloc < (now=time(NIL(time_t*)))) 112 break; 113 d = (double)(tloc-now); 114 if(shp->sigflag[SIGALRM]&SH_SIGTRAP) 115 sh_timetraps(); 116 } 117 return(0); 118 } 119 120 static void completed(void * handle) 121 { 122 char *expired = (char*)handle; 123 *expired = 1; 124 } 125 126 unsigned int sleep(unsigned int sec) 127 { 128 Shell_t *shp = &sh; 129 pid_t newpid, curpid=getpid(); 130 void *tp; 131 char expired = 0; 132 shp->lastsig = 0; 133 tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 134 do 135 { 136 if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0) 137 pause(); 138 if(shp->sigflag[SIGALRM]&SH_SIGTRAP) 139 sh_timetraps(); 140 if((newpid=getpid()) != curpid) 141 { 142 curpid = newpid; 143 shp->lastsig = 0; 144 shp->trapnote &= ~SH_SIGSET; 145 if(expired) 146 expired = 0; 147 else 148 timerdel(tp); 149 tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 150 } 151 } 152 while(!expired && shp->lastsig==0); 153 if(!expired) 154 timerdel(tp); 155 sh_sigcheck(); 156 return(0); 157 } 158 159 // 160 // Delay execution for time <t>. 161 // 162 void sh_delay(double t) { 163 Shell_t *shp = sh_getinterp(); 164 int n = (int)t; 165 Tv_t ts, tx; 166 167 ts.tv_sec = n; 168 ts.tv_nsec = 1000000000 * (t - (double)n); 169 while (tvsleep(&ts, &tx) < 0 && errno == EINTR) { 170 if (shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) return; 171 ts = tx; 172 } 173 } 174