121360Sdist /*
2*61111Sbostic * Copyright (c) 1989, 1993
3*61111Sbostic * The Regents of the University of California. All rights reserved.
439169Sbostic *
542626Sbostic * %sccs.include.redist.c%
621360Sdist */
721360Sdist
826593Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*61111Sbostic static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 06/04/93";
1039169Sbostic #endif /* LIBC_SCCS and not lint */
1112977Ssam
1213582Ssam #include <sys/time.h>
1339169Sbostic #include <sys/signal.h>
1446597Sdonn #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
2146597Sdonn unsigned int
sleep(seconds)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;
2946597Sdonn static void sleephandler();
301979Swnj
3139169Sbostic itp = &itv;
3239169Sbostic if (!seconds)
3346597Sdonn return 0;
3412977Ssam timerclear(&itp->it_interval);
3512977Ssam timerclear(&itp->it_value);
3612977Ssam if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
3746597Sdonn 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);
6446597Sdonn return 0;
651979Swnj }
661979Swnj
6739169Sbostic static void
sleephandler()6839169Sbostic sleephandler()
691979Swnj {
7014618Skarels ringring = 1;
711979Swnj }
72