1*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate /* 4*0Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 5*0Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 6*0Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 7*0Sstevel@tonic-gate */ 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gate /* 10*0Sstevel@tonic-gate * Copyright (c) 1986 by Sun Microsystems, Inc. 11*0Sstevel@tonic-gate */ 12*0Sstevel@tonic-gate 13*0Sstevel@tonic-gate #include <sys/time.h> 14*0Sstevel@tonic-gate #include <signal.h> 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate #define setvec(vec, a) \ 17*0Sstevel@tonic-gate vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gate /* 20*0Sstevel@tonic-gate * sleep(n) 21*0Sstevel@tonic-gate * 22*0Sstevel@tonic-gate * return 0 if n seconds passed 23*0Sstevel@tonic-gate * return n - t if t seconds passed 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * this code is gross and works just barely. 26*0Sstevel@tonic-gate * it would be nice if someone rewrote it. 27*0Sstevel@tonic-gate */ 28*0Sstevel@tonic-gate unsigned 29*0Sstevel@tonic-gate sleep(n) 30*0Sstevel@tonic-gate unsigned n; 31*0Sstevel@tonic-gate { 32*0Sstevel@tonic-gate void sleepx(); 33*0Sstevel@tonic-gate int omask; 34*0Sstevel@tonic-gate struct itimerval new, old, zero; 35*0Sstevel@tonic-gate register struct itimerval *newp = &new; 36*0Sstevel@tonic-gate struct timeval left_over; 37*0Sstevel@tonic-gate int alrm_flg; 38*0Sstevel@tonic-gate struct sigvec vec, ovec; 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate if (n == 0) 41*0Sstevel@tonic-gate return(0); 42*0Sstevel@tonic-gate timerclear(&newp->it_interval); 43*0Sstevel@tonic-gate timerclear(&newp->it_value); 44*0Sstevel@tonic-gate if (setitimer(ITIMER_REAL, newp, &old) < 0) 45*0Sstevel@tonic-gate return(n); 46*0Sstevel@tonic-gate newp->it_value.tv_sec = n; 47*0Sstevel@tonic-gate alrm_flg = 0; 48*0Sstevel@tonic-gate timerclear(&left_over); 49*0Sstevel@tonic-gate if (timerisset(&old.it_value)) { 50*0Sstevel@tonic-gate if (timercmp(&old.it_value, &newp->it_value, >)) { 51*0Sstevel@tonic-gate old.it_value.tv_sec -= newp->it_value.tv_sec; 52*0Sstevel@tonic-gate ++alrm_flg; 53*0Sstevel@tonic-gate } else { 54*0Sstevel@tonic-gate left_over.tv_sec = newp->it_value.tv_sec 55*0Sstevel@tonic-gate - old.it_value.tv_sec; 56*0Sstevel@tonic-gate if (old.it_value.tv_usec != 0) { 57*0Sstevel@tonic-gate left_over.tv_sec--; 58*0Sstevel@tonic-gate left_over.tv_usec = 1000000 59*0Sstevel@tonic-gate - old.it_value.tv_usec; 60*0Sstevel@tonic-gate } 61*0Sstevel@tonic-gate newp->it_value = old.it_value; 62*0Sstevel@tonic-gate timerclear(&old.it_value); 63*0Sstevel@tonic-gate --alrm_flg; 64*0Sstevel@tonic-gate } 65*0Sstevel@tonic-gate } 66*0Sstevel@tonic-gate if (alrm_flg >= 0) { 67*0Sstevel@tonic-gate setvec(vec, sleepx); 68*0Sstevel@tonic-gate (void) sigvec(SIGALRM, &vec, &ovec); 69*0Sstevel@tonic-gate } 70*0Sstevel@tonic-gate omask = sigblock(sigmask(SIGALRM)); 71*0Sstevel@tonic-gate (void) setitimer(ITIMER_REAL, newp, (struct itimerval *)0); 72*0Sstevel@tonic-gate sigpause(omask &~ sigmask(SIGALRM)); 73*0Sstevel@tonic-gate timerclear(&zero.it_value); 74*0Sstevel@tonic-gate timerclear(&zero.it_interval); 75*0Sstevel@tonic-gate (void) setitimer(ITIMER_REAL, &zero, newp); 76*0Sstevel@tonic-gate if (alrm_flg >= 0) 77*0Sstevel@tonic-gate (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 78*0Sstevel@tonic-gate (void) sigsetmask(omask); 79*0Sstevel@tonic-gate if (alrm_flg > 0 || (alrm_flg < 0 && timerisset(&newp->it_value))) { 80*0Sstevel@tonic-gate struct itimerval reset; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate /* 83*0Sstevel@tonic-gate * I use reset instead of what new points to because the 84*0Sstevel@tonic-gate * code that calculates the return value depends on the 85*0Sstevel@tonic-gate * old value of *newp. 86*0Sstevel@tonic-gate */ 87*0Sstevel@tonic-gate reset = *newp; 88*0Sstevel@tonic-gate newp = &reset; 89*0Sstevel@tonic-gate newp->it_value.tv_usec += old.it_value.tv_usec; 90*0Sstevel@tonic-gate newp->it_value.tv_sec += old.it_value.tv_sec; 91*0Sstevel@tonic-gate if (newp->it_value.tv_usec >= 1000000) { 92*0Sstevel@tonic-gate newp->it_value.tv_usec -= 1000000; 93*0Sstevel@tonic-gate newp->it_value.tv_sec++; 94*0Sstevel@tonic-gate } 95*0Sstevel@tonic-gate (void) setitimer(ITIMER_REAL, newp, (struct itimerval *)0); 96*0Sstevel@tonic-gate newp = &new; 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate left_over.tv_sec += newp->it_value.tv_sec; 99*0Sstevel@tonic-gate left_over.tv_usec += newp->it_value.tv_usec; 100*0Sstevel@tonic-gate if (left_over.tv_usec >= 1000000) { 101*0Sstevel@tonic-gate left_over.tv_sec++; 102*0Sstevel@tonic-gate left_over.tv_usec -= 1000000; 103*0Sstevel@tonic-gate } 104*0Sstevel@tonic-gate if (left_over.tv_usec >= 500000) 105*0Sstevel@tonic-gate left_over.tv_sec++; 106*0Sstevel@tonic-gate return(left_over.tv_sec); 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate static void 110*0Sstevel@tonic-gate sleepx() 111*0Sstevel@tonic-gate { 112*0Sstevel@tonic-gate } 113