1*5d54f3d8Smuffin /* 2*5d54f3d8Smuffin * Copyright 1986 Sun Microsystems, Inc. All rights reserved. 3*5d54f3d8Smuffin * Use is subject to license terms. 4*5d54f3d8Smuffin */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 87c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 97c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate 12*5d54f3d8Smuffin #pragma ident "%Z%%M% %I% %E% SMI" 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate #include <sys/time.h> 157c478bd9Sstevel@tonic-gate #include <signal.h> 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate #define setvec(vec, a) \ 187c478bd9Sstevel@tonic-gate vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 197c478bd9Sstevel@tonic-gate 20*5d54f3d8Smuffin static void sleepx(void); 21*5d54f3d8Smuffin 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * sleep(n) 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate * return 0 if n seconds passed 267c478bd9Sstevel@tonic-gate * return n - t if t seconds passed 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate * this code is gross and works just barely. 297c478bd9Sstevel@tonic-gate * it would be nice if someone rewrote it. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate unsigned 32*5d54f3d8Smuffin sleep(unsigned n) 337c478bd9Sstevel@tonic-gate { 347c478bd9Sstevel@tonic-gate int omask; 357c478bd9Sstevel@tonic-gate struct itimerval new, old, zero; 36*5d54f3d8Smuffin struct itimerval *newp = &new; 377c478bd9Sstevel@tonic-gate struct timeval left_over; 387c478bd9Sstevel@tonic-gate int alrm_flg; 397c478bd9Sstevel@tonic-gate struct sigvec vec, ovec; 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate if (n == 0) 427c478bd9Sstevel@tonic-gate return(0); 437c478bd9Sstevel@tonic-gate timerclear(&newp->it_interval); 447c478bd9Sstevel@tonic-gate timerclear(&newp->it_value); 457c478bd9Sstevel@tonic-gate if (setitimer(ITIMER_REAL, newp, &old) < 0) 467c478bd9Sstevel@tonic-gate return(n); 477c478bd9Sstevel@tonic-gate newp->it_value.tv_sec = n; 487c478bd9Sstevel@tonic-gate alrm_flg = 0; 497c478bd9Sstevel@tonic-gate timerclear(&left_over); 507c478bd9Sstevel@tonic-gate if (timerisset(&old.it_value)) { 517c478bd9Sstevel@tonic-gate if (timercmp(&old.it_value, &newp->it_value, >)) { 527c478bd9Sstevel@tonic-gate old.it_value.tv_sec -= newp->it_value.tv_sec; 537c478bd9Sstevel@tonic-gate ++alrm_flg; 547c478bd9Sstevel@tonic-gate } else { 557c478bd9Sstevel@tonic-gate left_over.tv_sec = newp->it_value.tv_sec 567c478bd9Sstevel@tonic-gate - old.it_value.tv_sec; 577c478bd9Sstevel@tonic-gate if (old.it_value.tv_usec != 0) { 587c478bd9Sstevel@tonic-gate left_over.tv_sec--; 597c478bd9Sstevel@tonic-gate left_over.tv_usec = 1000000 607c478bd9Sstevel@tonic-gate - old.it_value.tv_usec; 617c478bd9Sstevel@tonic-gate } 627c478bd9Sstevel@tonic-gate newp->it_value = old.it_value; 637c478bd9Sstevel@tonic-gate timerclear(&old.it_value); 647c478bd9Sstevel@tonic-gate --alrm_flg; 657c478bd9Sstevel@tonic-gate } 667c478bd9Sstevel@tonic-gate } 677c478bd9Sstevel@tonic-gate if (alrm_flg >= 0) { 687c478bd9Sstevel@tonic-gate setvec(vec, sleepx); 697c478bd9Sstevel@tonic-gate (void) sigvec(SIGALRM, &vec, &ovec); 707c478bd9Sstevel@tonic-gate } 717c478bd9Sstevel@tonic-gate omask = sigblock(sigmask(SIGALRM)); 727c478bd9Sstevel@tonic-gate (void) setitimer(ITIMER_REAL, newp, (struct itimerval *)0); 737c478bd9Sstevel@tonic-gate sigpause(omask &~ sigmask(SIGALRM)); 747c478bd9Sstevel@tonic-gate timerclear(&zero.it_value); 757c478bd9Sstevel@tonic-gate timerclear(&zero.it_interval); 767c478bd9Sstevel@tonic-gate (void) setitimer(ITIMER_REAL, &zero, newp); 777c478bd9Sstevel@tonic-gate if (alrm_flg >= 0) 787c478bd9Sstevel@tonic-gate (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 797c478bd9Sstevel@tonic-gate (void) sigsetmask(omask); 807c478bd9Sstevel@tonic-gate if (alrm_flg > 0 || (alrm_flg < 0 && timerisset(&newp->it_value))) { 817c478bd9Sstevel@tonic-gate struct itimerval reset; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate /* 847c478bd9Sstevel@tonic-gate * I use reset instead of what new points to because the 857c478bd9Sstevel@tonic-gate * code that calculates the return value depends on the 867c478bd9Sstevel@tonic-gate * old value of *newp. 877c478bd9Sstevel@tonic-gate */ 887c478bd9Sstevel@tonic-gate reset = *newp; 897c478bd9Sstevel@tonic-gate newp = &reset; 907c478bd9Sstevel@tonic-gate newp->it_value.tv_usec += old.it_value.tv_usec; 917c478bd9Sstevel@tonic-gate newp->it_value.tv_sec += old.it_value.tv_sec; 927c478bd9Sstevel@tonic-gate if (newp->it_value.tv_usec >= 1000000) { 937c478bd9Sstevel@tonic-gate newp->it_value.tv_usec -= 1000000; 947c478bd9Sstevel@tonic-gate newp->it_value.tv_sec++; 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate (void) setitimer(ITIMER_REAL, newp, (struct itimerval *)0); 977c478bd9Sstevel@tonic-gate newp = &new; 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate left_over.tv_sec += newp->it_value.tv_sec; 1007c478bd9Sstevel@tonic-gate left_over.tv_usec += newp->it_value.tv_usec; 1017c478bd9Sstevel@tonic-gate if (left_over.tv_usec >= 1000000) { 1027c478bd9Sstevel@tonic-gate left_over.tv_sec++; 1037c478bd9Sstevel@tonic-gate left_over.tv_usec -= 1000000; 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate if (left_over.tv_usec >= 500000) 1067c478bd9Sstevel@tonic-gate left_over.tv_sec++; 1077c478bd9Sstevel@tonic-gate return(left_over.tv_sec); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate static void 111*5d54f3d8Smuffin sleepx(void) 1127c478bd9Sstevel@tonic-gate { 1137c478bd9Sstevel@tonic-gate } 114