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