1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)sleep.c 5.5 (Berkeley) 06/01/90"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/time.h> 13 #include <sys/signal.h> 14 15 #define setvec(vec, a) \ 16 vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 17 18 static int ringring; 19 20 sleep(seconds) 21 unsigned int seconds; 22 { 23 register struct itimerval *itp; 24 struct itimerval itv, oitv; 25 struct sigvec vec, ovec; 26 long omask; 27 void sleephandler(); 28 29 itp = &itv; 30 if (!seconds) 31 return; 32 timerclear(&itp->it_interval); 33 timerclear(&itp->it_value); 34 if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 35 return; 36 itp->it_value.tv_sec = seconds; 37 if (timerisset(&oitv.it_value)) { 38 if (timercmp(&oitv.it_value, &itp->it_value, >)) 39 oitv.it_value.tv_sec -= itp->it_value.tv_sec; 40 else { 41 itp->it_value = oitv.it_value; 42 /* 43 * This is a hack, but we must have time to return 44 * from the setitimer after the alarm or else it'll 45 * be restarted. And, anyway, sleep never did 46 * anything more than this before. 47 */ 48 oitv.it_value.tv_sec = 1; 49 oitv.it_value.tv_usec = 0; 50 } 51 } 52 setvec(vec, sleephandler); 53 (void) sigvec(SIGALRM, &vec, &ovec); 54 omask = sigblock(sigmask(SIGALRM)); 55 ringring = 0; 56 (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 57 while (!ringring) 58 sigpause(omask &~ sigmask(SIGALRM)); 59 (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 60 (void) sigsetmask(omask); 61 (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 62 } 63 64 static void 65 sleephandler() 66 { 67 ringring = 1; 68 } 69