xref: /csrg-svn/lib/libc/gen/sleep.c (revision 39169)
121360Sdist /*
2*39169Sbostic  * Copyright (c) 1989 The Regents of the University of California.
3*39169Sbostic  * All rights reserved.
4*39169Sbostic  *
5*39169Sbostic  * Redistribution and use in source and binary forms are permitted
6*39169Sbostic  * provided that the above copyright notice and this paragraph are
7*39169Sbostic  * duplicated in all such forms and that any documentation,
8*39169Sbostic  * advertising materials, and other materials related to such
9*39169Sbostic  * distribution and use acknowledge that the software was developed
10*39169Sbostic  * by the University of California, Berkeley.  The name of the
11*39169Sbostic  * University may not be used to endorse or promote products derived
12*39169Sbostic  * from this software without specific prior written permission.
13*39169Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*39169Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*39169Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621360Sdist  */
1721360Sdist 
1826593Sdonn #if defined(LIBC_SCCS) && !defined(lint)
19*39169Sbostic static char sccsid[] = "@(#)sleep.c	5.4 (Berkeley) 09/18/89";
20*39169Sbostic #endif /* LIBC_SCCS and not lint */
2112977Ssam 
2213582Ssam #include <sys/time.h>
23*39169Sbostic #include <sys/signal.h>
241979Swnj 
2512977Ssam #define	setvec(vec, a) \
2612977Ssam 	vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
2712977Ssam 
2814618Skarels static int ringring;
2914618Skarels 
30*39169Sbostic sleep(seconds)
31*39169Sbostic 	unsigned int seconds;
321979Swnj {
33*39169Sbostic 	register struct itimerval *itp;
3412977Ssam 	struct itimerval itv, oitv;
3512977Ssam 	struct sigvec vec, ovec;
36*39169Sbostic 	long omask;
37*39169Sbostic 	void sleephandler();
381979Swnj 
39*39169Sbostic 	itp = &itv;
40*39169Sbostic 	if (!seconds)
411979Swnj 		return;
4212977Ssam 	timerclear(&itp->it_interval);
4312977Ssam 	timerclear(&itp->it_value);
4412977Ssam 	if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
4512977Ssam 		return;
46*39169Sbostic 	itp->it_value.tv_sec = seconds;
4712977Ssam 	if (timerisset(&oitv.it_value)) {
4812977Ssam 		if (timercmp(&oitv.it_value, &itp->it_value, >))
4912977Ssam 			oitv.it_value.tv_sec -= itp->it_value.tv_sec;
501979Swnj 		else {
5112977Ssam 			itp->it_value = oitv.it_value;
5212977Ssam 			/*
53*39169Sbostic 			 * This is a hack, but we must have time to return
54*39169Sbostic 			 * from the setitimer after the alarm or else it'll
55*39169Sbostic 			 * be restarted.  And, anyway, sleep never did
56*39169Sbostic 			 * anything more than this before.
5712977Ssam 			 */
5813019Ssam 			oitv.it_value.tv_sec = 1;
5913019Ssam 			oitv.it_value.tv_usec = 0;
601979Swnj 		}
611979Swnj 	}
62*39169Sbostic 	setvec(vec, sleephandler);
6312977Ssam 	(void) sigvec(SIGALRM, &vec, &ovec);
6417491Skarels 	omask = sigblock(sigmask(SIGALRM));
6514954Skarels 	ringring = 0;
6614618Skarels 	(void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0);
6714618Skarels 	while (!ringring)
6817491Skarels 		sigpause(omask &~ sigmask(SIGALRM));
6914618Skarels 	(void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);
7017491Skarels 	(void) sigsetmask(omask);
7114618Skarels 	(void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
721979Swnj }
731979Swnj 
74*39169Sbostic static void
75*39169Sbostic sleephandler()
761979Swnj {
7714618Skarels 	ringring = 1;
781979Swnj }
79