14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1982-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * David Korn <dgk@research.att.com> * 184887Schin * * 194887Schin ***********************************************************************/ 204887Schin #pragma prototyped 214887Schin /* 224887Schin * sleep delay 234887Schin * 244887Schin * David Korn 254887Schin * AT&T Labs 264887Schin * 274887Schin */ 284887Schin 294887Schin #define sleep ______sleep 304887Schin #include "defs.h" 314887Schin #undef sleep 324887Schin #include <error.h> 334887Schin #include <errno.h> 344887Schin #include "builtins.h" 354887Schin #include "FEATURE/time" 364887Schin #include "FEATURE/poll" 374887Schin #ifdef _NEXT_SOURCE 384887Schin # define sleep _ast_sleep 394887Schin #endif /* _NEXT_SOURCE */ 404887Schin #ifdef _lib_poll_notimer 414887Schin # undef _lib_poll 424887Schin #endif /* _lib_poll_notimer */ 434887Schin 444887Schin int b_sleep(register int argc,char *argv[],void *extra) 454887Schin { 464887Schin register char *cp; 474887Schin register double d; 48*8462SApril.Chin@Sun.COM register Shell_t *shp = ((Shbltin_t*)extra)->shp; 494887Schin time_t tloc = 0; 50*8462SApril.Chin@Sun.COM char *last; 51*8462SApril.Chin@Sun.COM if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF))) 52*8462SApril.Chin@Sun.COM sh_sigtrap(SIGALRM); 534887Schin while((argc = optget(argv,sh_optsleep))) switch(argc) 544887Schin { 554887Schin case ':': 564887Schin errormsg(SH_DICT,2, "%s", opt_info.arg); 574887Schin break; 584887Schin case '?': 594887Schin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); 604887Schin break; 614887Schin } 624887Schin argv += opt_info.index; 63*8462SApril.Chin@Sun.COM if(error_info.errors || !(cp= *argv) || ((d=strtod(cp, (char**)&last)),*last)) 644887Schin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); 65*8462SApril.Chin@Sun.COM if(d > .10) 664887Schin { 674887Schin time(&tloc); 684887Schin tloc += (time_t)(d+.5); 694887Schin } 704887Schin while(1) 714887Schin { 724887Schin time_t now; 734887Schin errno = 0; 744887Schin shp->lastsig=0; 754887Schin sh_delay(d); 764887Schin if(tloc==0 || errno!=EINTR || shp->lastsig) 774887Schin break; 784887Schin sh_sigcheck(); 794887Schin if(tloc < (now=time(NIL(time_t*)))) 804887Schin break; 814887Schin d = (double)(tloc-now); 824887Schin if(shp->sigflag[SIGALRM]&SH_SIGTRAP) 834887Schin sh_timetraps(); 844887Schin } 854887Schin return(0); 864887Schin } 874887Schin 884887Schin static void completed(void * handle) 894887Schin { 904887Schin char *expired = (char*)handle; 914887Schin *expired = 1; 924887Schin } 934887Schin 944887Schin unsigned int sleep(unsigned int sec) 954887Schin { 96*8462SApril.Chin@Sun.COM Shell_t *shp = &sh; 974887Schin pid_t newpid, curpid=getpid(); 984887Schin void *tp; 994887Schin char expired = 0; 100*8462SApril.Chin@Sun.COM shp->lastsig = 0; 1014887Schin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 1024887Schin do 1034887Schin { 104*8462SApril.Chin@Sun.COM if(!shp->waitevent || (*shp->waitevent)(-1,-1L,0)==0) 1054887Schin pause(); 106*8462SApril.Chin@Sun.COM if(shp->sigflag[SIGALRM]&SH_SIGTRAP) 1074887Schin sh_timetraps(); 1084887Schin if((newpid=getpid()) != curpid) 1094887Schin { 1104887Schin curpid = newpid; 111*8462SApril.Chin@Sun.COM shp->lastsig = 0; 112*8462SApril.Chin@Sun.COM shp->trapnote &= ~SH_SIGSET; 1134887Schin if(expired) 1144887Schin expired = 0; 1154887Schin else 1164887Schin timerdel(tp); 1174887Schin tp = (void*)sh_timeradd(1000*sec, 0, completed, (void*)&expired); 1184887Schin } 1194887Schin } 120*8462SApril.Chin@Sun.COM while(!expired && shp->lastsig==0); 1214887Schin if(!expired) 1224887Schin timerdel(tp); 1234887Schin sh_sigcheck(); 1244887Schin return(0); 1254887Schin } 1264887Schin 1274887Schin /* 1284887Schin * delay execution for time <t> 1294887Schin */ 1304887Schin 1314887Schin void sh_delay(double t) 1324887Schin { 1334887Schin register int n = (int)t; 134*8462SApril.Chin@Sun.COM Shell_t *shp = &sh; 1354887Schin #ifdef _lib_poll 1364887Schin struct pollfd fd; 1374887Schin if(t<=0) 1384887Schin return; 1394887Schin else if(n > 30) 1404887Schin { 1414887Schin sleep(n); 1424887Schin t -= n; 1434887Schin } 1444887Schin if(n=(int)(1000*t)) 1454887Schin { 146*8462SApril.Chin@Sun.COM if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0) 1474887Schin poll(&fd,0,n); 1484887Schin } 1494887Schin #else 1504887Schin # if defined(_lib_select) && defined(_mem_tv_usec_timeval) 1514887Schin struct timeval timeloc; 1524887Schin if(t<=0) 1534887Schin return; 154*8462SApril.Chin@Sun.COM if(n=(int)(1000*t) && shp->waitevent && (*shp->waitevent)(-1,(long)n,0)) 1554887Schin return; 1564887Schin n = (int)t; 1574887Schin timeloc.tv_sec = n; 1584887Schin timeloc.tv_usec = 1000000*(t-(double)n); 1594887Schin select(0,(fd_set*)0,(fd_set*)0,(fd_set*)0,&timeloc); 1604887Schin # else 1614887Schin # ifdef _lib_select 1624887Schin /* for 9th edition machines */ 1634887Schin if(t<=0) 1644887Schin return; 1654887Schin if(n > 30) 1664887Schin { 1674887Schin sleep(n); 1684887Schin t -= n; 1694887Schin } 1704887Schin if(n=(int)(1000*t)) 1714887Schin { 172*8462SApril.Chin@Sun.COM if(!shp->waitevent || (*shp->waitevent)(-1,(long)n,0)==0) 1734887Schin select(0,(fd_set*)0,(fd_set*)0,n); 1744887Schin } 1754887Schin # else 1764887Schin struct tms tt; 1774887Schin if(t<=0) 1784887Schin return; 1794887Schin sleep(n); 1804887Schin t -= n; 1814887Schin if(t) 1824887Schin { 1834887Schin clock_t begin = times(&tt); 1844887Schin if(begin==0) 1854887Schin return; 186*8462SApril.Chin@Sun.COM t *= shp->lim.clk_tck; 1874887Schin n += (t+.5); 1884887Schin while((times(&tt)-begin) < n); 1894887Schin } 1904887Schin # endif 1914887Schin # endif 1924887Schin #endif /* _lib_poll */ 1934887Schin } 194