121360Sdist /* 239169Sbostic * Copyright (c) 1989 The Regents of the University of California. 339169Sbostic * All rights reserved. 439169Sbostic * 542626Sbostic * %sccs.include.redist.c% 621360Sdist */ 721360Sdist 826593Sdonn #if defined(LIBC_SCCS) && !defined(lint) 9*46597Sdonn static char sccsid[] = "@(#)sleep.c 5.6 (Berkeley) 02/23/91"; 1039169Sbostic #endif /* LIBC_SCCS and not lint */ 1112977Ssam 1213582Ssam #include <sys/time.h> 1339169Sbostic #include <sys/signal.h> 14*46597Sdonn #include <unistd.h> 151979Swnj 1612977Ssam #define setvec(vec, a) \ 1712977Ssam vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 1812977Ssam 1914618Skarels static int ringring; 2014618Skarels 21*46597Sdonn unsigned int 2239169Sbostic sleep(seconds) 2339169Sbostic unsigned int seconds; 241979Swnj { 2539169Sbostic register struct itimerval *itp; 2612977Ssam struct itimerval itv, oitv; 2712977Ssam struct sigvec vec, ovec; 2839169Sbostic long omask; 29*46597Sdonn static void sleephandler(); 301979Swnj 3139169Sbostic itp = &itv; 3239169Sbostic if (!seconds) 33*46597Sdonn return 0; 3412977Ssam timerclear(&itp->it_interval); 3512977Ssam timerclear(&itp->it_value); 3612977Ssam if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 37*46597Sdonn return seconds; 3839169Sbostic itp->it_value.tv_sec = seconds; 3912977Ssam if (timerisset(&oitv.it_value)) { 4012977Ssam if (timercmp(&oitv.it_value, &itp->it_value, >)) 4112977Ssam oitv.it_value.tv_sec -= itp->it_value.tv_sec; 421979Swnj else { 4312977Ssam itp->it_value = oitv.it_value; 4412977Ssam /* 4539169Sbostic * This is a hack, but we must have time to return 4639169Sbostic * from the setitimer after the alarm or else it'll 4739169Sbostic * be restarted. And, anyway, sleep never did 4839169Sbostic * anything more than this before. 4912977Ssam */ 5013019Ssam oitv.it_value.tv_sec = 1; 5113019Ssam oitv.it_value.tv_usec = 0; 521979Swnj } 531979Swnj } 5439169Sbostic setvec(vec, sleephandler); 5512977Ssam (void) sigvec(SIGALRM, &vec, &ovec); 5617491Skarels omask = sigblock(sigmask(SIGALRM)); 5714954Skarels ringring = 0; 5814618Skarels (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 5914618Skarels while (!ringring) 6017491Skarels sigpause(omask &~ sigmask(SIGALRM)); 6114618Skarels (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 6217491Skarels (void) sigsetmask(omask); 6314618Skarels (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 64*46597Sdonn return 0; 651979Swnj } 661979Swnj 6739169Sbostic static void 6839169Sbostic sleephandler() 691979Swnj { 7014618Skarels ringring = 1; 711979Swnj } 72