xref: /titanic_41/usr/src/cmd/sendmail/libsm/clock.c (revision 49218d4f8e4d84d1c08aeb267bcf6e451f2056dc)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
37c478bd9Sstevel@tonic-gate  *	All rights reserved.
47c478bd9Sstevel@tonic-gate  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
57c478bd9Sstevel@tonic-gate  * Copyright (c) 1988, 1993
67c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
97c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
107c478bd9Sstevel@tonic-gate  * the sendmail distribution.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  */
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate #include <sm/gen.h>
17*49218d4fSjbeck SM_RCSID("@(#)$Id: clock.c,v 1.47 2005/06/14 23:07:20 ca Exp $")
187c478bd9Sstevel@tonic-gate #include <unistd.h>
197c478bd9Sstevel@tonic-gate #include <time.h>
207c478bd9Sstevel@tonic-gate #include <errno.h>
217c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
22*49218d4fSjbeck # include <sm/time.h>
237c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
247c478bd9Sstevel@tonic-gate #include <sm/heap.h>
257c478bd9Sstevel@tonic-gate #include <sm/debug.h>
267c478bd9Sstevel@tonic-gate #include <sm/bitops.h>
277c478bd9Sstevel@tonic-gate #include <sm/clock.h>
287c478bd9Sstevel@tonic-gate #include "local.h"
297c478bd9Sstevel@tonic-gate #if _FFR_SLEEP_USE_SELECT > 0
307c478bd9Sstevel@tonic-gate # include <sys/types.h>
317c478bd9Sstevel@tonic-gate #endif /* _FFR_SLEEP_USE_SELECT > 0 */
327c478bd9Sstevel@tonic-gate #if defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2
337c478bd9Sstevel@tonic-gate # include <syslog.h>
347c478bd9Sstevel@tonic-gate #endif /* defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #ifndef sigmask
377c478bd9Sstevel@tonic-gate # define sigmask(s)	(1 << ((s) - 1))
387c478bd9Sstevel@tonic-gate #endif /* ! sigmask */
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate **  SM_SETEVENTM -- set an event to happen at a specific time in milliseconds.
437c478bd9Sstevel@tonic-gate **
447c478bd9Sstevel@tonic-gate **	Events are stored in a sorted list for fast processing.
457c478bd9Sstevel@tonic-gate **	An event only applies to the process that set it.
467c478bd9Sstevel@tonic-gate **	Source is #ifdef'd to work with older OS's that don't have setitimer()
477c478bd9Sstevel@tonic-gate **	(that is, don't have a timer granularity less than 1 second).
487c478bd9Sstevel@tonic-gate **
497c478bd9Sstevel@tonic-gate **	Parameters:
507c478bd9Sstevel@tonic-gate **		intvl -- interval until next event occurs (milliseconds).
517c478bd9Sstevel@tonic-gate **		func -- function to call on event.
527c478bd9Sstevel@tonic-gate **		arg -- argument to func on event.
537c478bd9Sstevel@tonic-gate **
547c478bd9Sstevel@tonic-gate **	Returns:
557c478bd9Sstevel@tonic-gate **		On success returns the SM_EVENT entry created.
567c478bd9Sstevel@tonic-gate **		On failure returns NULL.
577c478bd9Sstevel@tonic-gate **
587c478bd9Sstevel@tonic-gate **	Side Effects:
597c478bd9Sstevel@tonic-gate **		none.
607c478bd9Sstevel@tonic-gate */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate static SM_EVENT	*volatile SmEventQueue;		/* head of event queue */
637c478bd9Sstevel@tonic-gate static SM_EVENT	*volatile SmFreeEventList;	/* list of free events */
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate SM_EVENT *
sm_seteventm(intvl,func,arg)667c478bd9Sstevel@tonic-gate sm_seteventm(intvl, func, arg)
677c478bd9Sstevel@tonic-gate 	int intvl;
687c478bd9Sstevel@tonic-gate 	void (*func)__P((int));
697c478bd9Sstevel@tonic-gate 	int arg;
707c478bd9Sstevel@tonic-gate {
717c478bd9Sstevel@tonic-gate 	ENTER_CRITICAL();
727c478bd9Sstevel@tonic-gate 	if (SmFreeEventList == NULL)
737c478bd9Sstevel@tonic-gate 	{
747c478bd9Sstevel@tonic-gate 		SmFreeEventList = (SM_EVENT *) sm_pmalloc_x(sizeof *SmFreeEventList);
757c478bd9Sstevel@tonic-gate 		SmFreeEventList->ev_link = NULL;
767c478bd9Sstevel@tonic-gate 	}
777c478bd9Sstevel@tonic-gate 	LEAVE_CRITICAL();
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	return sm_sigsafe_seteventm(intvl, func, arg);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
847c478bd9Sstevel@tonic-gate **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
857c478bd9Sstevel@tonic-gate **		DOING.
867c478bd9Sstevel@tonic-gate */
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate SM_EVENT *
sm_sigsafe_seteventm(intvl,func,arg)897c478bd9Sstevel@tonic-gate sm_sigsafe_seteventm(intvl, func, arg)
907c478bd9Sstevel@tonic-gate 	int intvl;
917c478bd9Sstevel@tonic-gate 	void (*func)__P((int));
927c478bd9Sstevel@tonic-gate 	int arg;
937c478bd9Sstevel@tonic-gate {
947c478bd9Sstevel@tonic-gate 	register SM_EVENT **evp;
957c478bd9Sstevel@tonic-gate 	register SM_EVENT *ev;
967c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
977c478bd9Sstevel@tonic-gate 	auto struct timeval now, nowi, ival;
987c478bd9Sstevel@tonic-gate 	auto struct itimerval itime;
997c478bd9Sstevel@tonic-gate #else /*  SM_CONF_SETITIMER */
1007c478bd9Sstevel@tonic-gate 	auto time_t now, nowi;
1017c478bd9Sstevel@tonic-gate #endif /*  SM_CONF_SETITIMER */
1027c478bd9Sstevel@tonic-gate 	int wasblocked;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 	/* negative times are not allowed */
1057c478bd9Sstevel@tonic-gate 	if (intvl <= 0)
1067c478bd9Sstevel@tonic-gate 		return NULL;
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	wasblocked = sm_blocksignal(SIGALRM);
1097c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
1107c478bd9Sstevel@tonic-gate 	ival.tv_sec = intvl / 1000;
1117c478bd9Sstevel@tonic-gate 	ival.tv_usec = (intvl - ival.tv_sec * 1000) * 10;
1127c478bd9Sstevel@tonic-gate 	(void) gettimeofday(&now, NULL);
1137c478bd9Sstevel@tonic-gate 	nowi = now;
1147c478bd9Sstevel@tonic-gate 	timeradd(&now, &ival, &nowi);
1157c478bd9Sstevel@tonic-gate #else /*  SM_CONF_SETITIMER */
1167c478bd9Sstevel@tonic-gate 	now = time(NULL);
1177c478bd9Sstevel@tonic-gate 	nowi = now + (time_t)(intvl / 1000);
1187c478bd9Sstevel@tonic-gate #endif /*  SM_CONF_SETITIMER */
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	/* search event queue for correct position */
1217c478bd9Sstevel@tonic-gate 	for (evp = (SM_EVENT **) (&SmEventQueue);
1227c478bd9Sstevel@tonic-gate 	     (ev = *evp) != NULL;
1237c478bd9Sstevel@tonic-gate 	     evp = &ev->ev_link)
1247c478bd9Sstevel@tonic-gate 	{
1257c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
1267c478bd9Sstevel@tonic-gate 		if (timercmp(&(ev->ev_time), &nowi, >=))
1277c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
1287c478bd9Sstevel@tonic-gate 		if (ev->ev_time >= nowi)
1297c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
1307c478bd9Sstevel@tonic-gate 			break;
1317c478bd9Sstevel@tonic-gate 	}
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	ENTER_CRITICAL();
1347c478bd9Sstevel@tonic-gate 	if (SmFreeEventList == NULL)
1357c478bd9Sstevel@tonic-gate 	{
1367c478bd9Sstevel@tonic-gate 		/*
1377c478bd9Sstevel@tonic-gate 		**  This shouldn't happen.  If called from sm_seteventm(),
1387c478bd9Sstevel@tonic-gate 		**  we have just malloced a SmFreeEventList entry.  If
1397c478bd9Sstevel@tonic-gate 		**  called from a signal handler, it should have been
1407c478bd9Sstevel@tonic-gate 		**  from an existing event which sm_tick() just added to
1417c478bd9Sstevel@tonic-gate 		**  SmFreeEventList.
1427c478bd9Sstevel@tonic-gate 		*/
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 		LEAVE_CRITICAL();
1457c478bd9Sstevel@tonic-gate 		if (wasblocked == 0)
1467c478bd9Sstevel@tonic-gate 			(void) sm_releasesignal(SIGALRM);
1477c478bd9Sstevel@tonic-gate 		return NULL;
1487c478bd9Sstevel@tonic-gate 	}
1497c478bd9Sstevel@tonic-gate 	else
1507c478bd9Sstevel@tonic-gate 	{
1517c478bd9Sstevel@tonic-gate 		ev = SmFreeEventList;
1527c478bd9Sstevel@tonic-gate 		SmFreeEventList = ev->ev_link;
1537c478bd9Sstevel@tonic-gate 	}
1547c478bd9Sstevel@tonic-gate 	LEAVE_CRITICAL();
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	/* insert new event */
1577c478bd9Sstevel@tonic-gate 	ev->ev_time = nowi;
1587c478bd9Sstevel@tonic-gate 	ev->ev_func = func;
1597c478bd9Sstevel@tonic-gate 	ev->ev_arg = arg;
1607c478bd9Sstevel@tonic-gate 	ev->ev_pid = getpid();
1617c478bd9Sstevel@tonic-gate 	ENTER_CRITICAL();
1627c478bd9Sstevel@tonic-gate 	ev->ev_link = *evp;
1637c478bd9Sstevel@tonic-gate 	*evp = ev;
1647c478bd9Sstevel@tonic-gate 	LEAVE_CRITICAL();
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	(void) sm_signal(SIGALRM, sm_tick);
1677c478bd9Sstevel@tonic-gate # if SM_CONF_SETITIMER
1687c478bd9Sstevel@tonic-gate 	timersub(&SmEventQueue->ev_time, &now, &itime.it_value);
1697c478bd9Sstevel@tonic-gate 	itime.it_interval.tv_sec = 0;
1707c478bd9Sstevel@tonic-gate 	itime.it_interval.tv_usec = 0;
1717c478bd9Sstevel@tonic-gate 	if (itime.it_value.tv_sec < 0)
1727c478bd9Sstevel@tonic-gate 		itime.it_value.tv_sec = 0;
1737c478bd9Sstevel@tonic-gate 	if (itime.it_value.tv_sec == 0 && itime.it_value.tv_usec == 0)
1747c478bd9Sstevel@tonic-gate 		itime.it_value.tv_usec = 1000;
1757c478bd9Sstevel@tonic-gate 	(void) setitimer(ITIMER_REAL, &itime, NULL);
1767c478bd9Sstevel@tonic-gate # else /* SM_CONF_SETITIMER */
1777c478bd9Sstevel@tonic-gate 	intvl = SmEventQueue->ev_time - now;
1787c478bd9Sstevel@tonic-gate 	(void) alarm((unsigned) (intvl < 1 ? 1 : intvl));
1797c478bd9Sstevel@tonic-gate # endif /* SM_CONF_SETITIMER */
1807c478bd9Sstevel@tonic-gate 	if (wasblocked == 0)
1817c478bd9Sstevel@tonic-gate 		(void) sm_releasesignal(SIGALRM);
1827c478bd9Sstevel@tonic-gate 	return ev;
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate **  SM_CLREVENT -- remove an event from the event queue.
1867c478bd9Sstevel@tonic-gate **
1877c478bd9Sstevel@tonic-gate **	Parameters:
1887c478bd9Sstevel@tonic-gate **		ev -- pointer to event to remove.
1897c478bd9Sstevel@tonic-gate **
1907c478bd9Sstevel@tonic-gate **	Returns:
1917c478bd9Sstevel@tonic-gate **		none.
1927c478bd9Sstevel@tonic-gate **
1937c478bd9Sstevel@tonic-gate **	Side Effects:
1947c478bd9Sstevel@tonic-gate **		arranges for event ev to not happen.
1957c478bd9Sstevel@tonic-gate */
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate void
sm_clrevent(ev)1987c478bd9Sstevel@tonic-gate sm_clrevent(ev)
1997c478bd9Sstevel@tonic-gate 	register SM_EVENT *ev;
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate 	register SM_EVENT **evp;
2027c478bd9Sstevel@tonic-gate 	int wasblocked;
2037c478bd9Sstevel@tonic-gate # if SM_CONF_SETITIMER
2047c478bd9Sstevel@tonic-gate 	struct itimerval clr;
2057c478bd9Sstevel@tonic-gate # endif /* SM_CONF_SETITIMER */
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	if (ev == NULL)
2087c478bd9Sstevel@tonic-gate 		return;
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	/* find the parent event */
2117c478bd9Sstevel@tonic-gate 	wasblocked = sm_blocksignal(SIGALRM);
2127c478bd9Sstevel@tonic-gate 	for (evp = (SM_EVENT **) (&SmEventQueue);
2137c478bd9Sstevel@tonic-gate 	     *evp != NULL;
2147c478bd9Sstevel@tonic-gate 	     evp = &(*evp)->ev_link)
2157c478bd9Sstevel@tonic-gate 	{
2167c478bd9Sstevel@tonic-gate 		if (*evp == ev)
2177c478bd9Sstevel@tonic-gate 			break;
2187c478bd9Sstevel@tonic-gate 	}
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	/* now remove it */
2217c478bd9Sstevel@tonic-gate 	if (*evp != NULL)
2227c478bd9Sstevel@tonic-gate 	{
2237c478bd9Sstevel@tonic-gate 		ENTER_CRITICAL();
2247c478bd9Sstevel@tonic-gate 		*evp = ev->ev_link;
2257c478bd9Sstevel@tonic-gate 		ev->ev_link = SmFreeEventList;
2267c478bd9Sstevel@tonic-gate 		SmFreeEventList = ev;
2277c478bd9Sstevel@tonic-gate 		LEAVE_CRITICAL();
2287c478bd9Sstevel@tonic-gate 	}
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	/* restore clocks and pick up anything spare */
2317c478bd9Sstevel@tonic-gate 	if (wasblocked == 0)
2327c478bd9Sstevel@tonic-gate 		(void) sm_releasesignal(SIGALRM);
2337c478bd9Sstevel@tonic-gate 	if (SmEventQueue != NULL)
2347c478bd9Sstevel@tonic-gate 		(void) kill(getpid(), SIGALRM);
2357c478bd9Sstevel@tonic-gate 	else
2367c478bd9Sstevel@tonic-gate 	{
2377c478bd9Sstevel@tonic-gate 		/* nothing left in event queue, no need for an alarm */
2387c478bd9Sstevel@tonic-gate # if SM_CONF_SETITIMER
2397c478bd9Sstevel@tonic-gate 		clr.it_interval.tv_sec = 0;
2407c478bd9Sstevel@tonic-gate 		clr.it_interval.tv_usec = 0;
2417c478bd9Sstevel@tonic-gate 		clr.it_value.tv_sec = 0;
2427c478bd9Sstevel@tonic-gate 		clr.it_value.tv_usec = 0;
2437c478bd9Sstevel@tonic-gate 		(void) setitimer(ITIMER_REAL, &clr, NULL);
2447c478bd9Sstevel@tonic-gate # else /* SM_CONF_SETITIMER */
2457c478bd9Sstevel@tonic-gate 		(void) alarm(0);
2467c478bd9Sstevel@tonic-gate # endif /* SM_CONF_SETITIMER */
2477c478bd9Sstevel@tonic-gate 	}
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate /*
2507c478bd9Sstevel@tonic-gate **  SM_CLEAR_EVENTS -- remove all events from the event queue.
2517c478bd9Sstevel@tonic-gate **
2527c478bd9Sstevel@tonic-gate **	Parameters:
2537c478bd9Sstevel@tonic-gate **		none.
2547c478bd9Sstevel@tonic-gate **
2557c478bd9Sstevel@tonic-gate **	Returns:
2567c478bd9Sstevel@tonic-gate **		none.
2577c478bd9Sstevel@tonic-gate */
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate void
sm_clear_events()2607c478bd9Sstevel@tonic-gate sm_clear_events()
2617c478bd9Sstevel@tonic-gate {
2627c478bd9Sstevel@tonic-gate 	register SM_EVENT *ev;
2637c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
2647c478bd9Sstevel@tonic-gate 	struct itimerval clr;
2657c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
2667c478bd9Sstevel@tonic-gate 	int wasblocked;
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 	/* nothing will be left in event queue, no need for an alarm */
2697c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
2707c478bd9Sstevel@tonic-gate 	clr.it_interval.tv_sec = 0;
2717c478bd9Sstevel@tonic-gate 	clr.it_interval.tv_usec = 0;
2727c478bd9Sstevel@tonic-gate 	clr.it_value.tv_sec = 0;
2737c478bd9Sstevel@tonic-gate 	clr.it_value.tv_usec = 0;
2747c478bd9Sstevel@tonic-gate 	(void) setitimer(ITIMER_REAL, &clr, NULL);
2757c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
2767c478bd9Sstevel@tonic-gate 	(void) alarm(0);
2777c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	if (SmEventQueue == NULL)
2807c478bd9Sstevel@tonic-gate 		return;
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	wasblocked = sm_blocksignal(SIGALRM);
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	/* find the end of the EventQueue */
2857c478bd9Sstevel@tonic-gate 	for (ev = SmEventQueue; ev->ev_link != NULL; ev = ev->ev_link)
2867c478bd9Sstevel@tonic-gate 		continue;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 	ENTER_CRITICAL();
2897c478bd9Sstevel@tonic-gate 	ev->ev_link = SmFreeEventList;
2907c478bd9Sstevel@tonic-gate 	SmFreeEventList = SmEventQueue;
2917c478bd9Sstevel@tonic-gate 	SmEventQueue = NULL;
2927c478bd9Sstevel@tonic-gate 	LEAVE_CRITICAL();
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	/* restore clocks and pick up anything spare */
2957c478bd9Sstevel@tonic-gate 	if (wasblocked == 0)
2967c478bd9Sstevel@tonic-gate 		(void) sm_releasesignal(SIGALRM);
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate /*
2997c478bd9Sstevel@tonic-gate **  SM_TICK -- take a clock tick
3007c478bd9Sstevel@tonic-gate **
3017c478bd9Sstevel@tonic-gate **	Called by the alarm clock.  This routine runs events as needed.
3027c478bd9Sstevel@tonic-gate **	Always called as a signal handler, so we assume that SIGALRM
3037c478bd9Sstevel@tonic-gate **	has been blocked.
3047c478bd9Sstevel@tonic-gate **
3057c478bd9Sstevel@tonic-gate **	Parameters:
3067c478bd9Sstevel@tonic-gate **		One that is ignored; for compatibility with signal handlers.
3077c478bd9Sstevel@tonic-gate **
3087c478bd9Sstevel@tonic-gate **	Returns:
3097c478bd9Sstevel@tonic-gate **		none.
3107c478bd9Sstevel@tonic-gate **
3117c478bd9Sstevel@tonic-gate **	Side Effects:
3127c478bd9Sstevel@tonic-gate **		calls the next function in EventQueue.
3137c478bd9Sstevel@tonic-gate **
3147c478bd9Sstevel@tonic-gate **	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
3157c478bd9Sstevel@tonic-gate **		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3167c478bd9Sstevel@tonic-gate **		DOING.
3177c478bd9Sstevel@tonic-gate */
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate /* ARGSUSED */
3207c478bd9Sstevel@tonic-gate SIGFUNC_DECL
sm_tick(sig)3217c478bd9Sstevel@tonic-gate sm_tick(sig)
3227c478bd9Sstevel@tonic-gate 	int sig;
3237c478bd9Sstevel@tonic-gate {
3247c478bd9Sstevel@tonic-gate 	register SM_EVENT *ev;
3257c478bd9Sstevel@tonic-gate 	pid_t mypid;
3267c478bd9Sstevel@tonic-gate 	int save_errno = errno;
3277c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
3287c478bd9Sstevel@tonic-gate 	struct itimerval clr;
3297c478bd9Sstevel@tonic-gate 	struct timeval now;
3307c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
3317c478bd9Sstevel@tonic-gate 	register time_t now;
3327c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
3357c478bd9Sstevel@tonic-gate 	clr.it_interval.tv_sec = 0;
3367c478bd9Sstevel@tonic-gate 	clr.it_interval.tv_usec = 0;
3377c478bd9Sstevel@tonic-gate 	clr.it_value.tv_sec = 0;
3387c478bd9Sstevel@tonic-gate 	clr.it_value.tv_usec = 0;
3397c478bd9Sstevel@tonic-gate 	(void) setitimer(ITIMER_REAL, &clr, NULL);
3407c478bd9Sstevel@tonic-gate 	gettimeofday(&now, NULL);
3417c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
3427c478bd9Sstevel@tonic-gate 	(void) alarm(0);
3437c478bd9Sstevel@tonic-gate 	now = time(NULL);
3447c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	FIX_SYSV_SIGNAL(sig, sm_tick);
3477c478bd9Sstevel@tonic-gate 	errno = save_errno;
3487c478bd9Sstevel@tonic-gate 	CHECK_CRITICAL(sig);
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 	mypid = getpid();
3517c478bd9Sstevel@tonic-gate 	while (PendingSignal != 0)
3527c478bd9Sstevel@tonic-gate 	{
3537c478bd9Sstevel@tonic-gate 		int sigbit = 0;
3547c478bd9Sstevel@tonic-gate 		int sig = 0;
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 		if (bitset(PEND_SIGHUP, PendingSignal))
3577c478bd9Sstevel@tonic-gate 		{
3587c478bd9Sstevel@tonic-gate 			sigbit = PEND_SIGHUP;
3597c478bd9Sstevel@tonic-gate 			sig = SIGHUP;
3607c478bd9Sstevel@tonic-gate 		}
3617c478bd9Sstevel@tonic-gate 		else if (bitset(PEND_SIGINT, PendingSignal))
3627c478bd9Sstevel@tonic-gate 		{
3637c478bd9Sstevel@tonic-gate 			sigbit = PEND_SIGINT;
3647c478bd9Sstevel@tonic-gate 			sig = SIGINT;
3657c478bd9Sstevel@tonic-gate 		}
3667c478bd9Sstevel@tonic-gate 		else if (bitset(PEND_SIGTERM, PendingSignal))
3677c478bd9Sstevel@tonic-gate 		{
3687c478bd9Sstevel@tonic-gate 			sigbit = PEND_SIGTERM;
3697c478bd9Sstevel@tonic-gate 			sig = SIGTERM;
3707c478bd9Sstevel@tonic-gate 		}
3717c478bd9Sstevel@tonic-gate 		else if (bitset(PEND_SIGUSR1, PendingSignal))
3727c478bd9Sstevel@tonic-gate 		{
3737c478bd9Sstevel@tonic-gate 			sigbit = PEND_SIGUSR1;
3747c478bd9Sstevel@tonic-gate 			sig = SIGUSR1;
3757c478bd9Sstevel@tonic-gate 		}
3767c478bd9Sstevel@tonic-gate 		else
3777c478bd9Sstevel@tonic-gate 		{
3787c478bd9Sstevel@tonic-gate 			/* If we get here, we are in trouble */
3797c478bd9Sstevel@tonic-gate 			abort();
3807c478bd9Sstevel@tonic-gate 		}
3817c478bd9Sstevel@tonic-gate 		PendingSignal &= ~sigbit;
3827c478bd9Sstevel@tonic-gate 		kill(mypid, sig);
3837c478bd9Sstevel@tonic-gate 	}
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
3867c478bd9Sstevel@tonic-gate 	gettimeofday(&now, NULL);
3877c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
3887c478bd9Sstevel@tonic-gate 	now = time(NULL);
3897c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
3907c478bd9Sstevel@tonic-gate 	while ((ev = SmEventQueue) != NULL &&
3917c478bd9Sstevel@tonic-gate 	       (ev->ev_pid != mypid ||
3927c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
3937c478bd9Sstevel@tonic-gate 		timercmp(&ev->ev_time, &now, <=)
3947c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
3957c478bd9Sstevel@tonic-gate 		ev->ev_time <= now
3967c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
3977c478bd9Sstevel@tonic-gate 		))
3987c478bd9Sstevel@tonic-gate 	{
3997c478bd9Sstevel@tonic-gate 		void (*f)__P((int));
4007c478bd9Sstevel@tonic-gate 		int arg;
4017c478bd9Sstevel@tonic-gate 		pid_t pid;
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate 		/* process the event on the top of the queue */
4047c478bd9Sstevel@tonic-gate 		ev = SmEventQueue;
4057c478bd9Sstevel@tonic-gate 		SmEventQueue = SmEventQueue->ev_link;
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 		/* we must be careful in here because ev_func may not return */
4087c478bd9Sstevel@tonic-gate 		f = ev->ev_func;
4097c478bd9Sstevel@tonic-gate 		arg = ev->ev_arg;
4107c478bd9Sstevel@tonic-gate 		pid = ev->ev_pid;
4117c478bd9Sstevel@tonic-gate 		ENTER_CRITICAL();
4127c478bd9Sstevel@tonic-gate 		ev->ev_link = SmFreeEventList;
4137c478bd9Sstevel@tonic-gate 		SmFreeEventList = ev;
4147c478bd9Sstevel@tonic-gate 		LEAVE_CRITICAL();
4157c478bd9Sstevel@tonic-gate 		if (pid != getpid())
4167c478bd9Sstevel@tonic-gate 			continue;
4177c478bd9Sstevel@tonic-gate 		if (SmEventQueue != NULL)
4187c478bd9Sstevel@tonic-gate 		{
4197c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
4207c478bd9Sstevel@tonic-gate 			if (timercmp(&SmEventQueue->ev_time, &now, >))
4217c478bd9Sstevel@tonic-gate 			{
4227c478bd9Sstevel@tonic-gate 				timersub(&SmEventQueue->ev_time, &now,
4237c478bd9Sstevel@tonic-gate 					 &clr.it_value);
4247c478bd9Sstevel@tonic-gate 				clr.it_interval.tv_sec = 0;
4257c478bd9Sstevel@tonic-gate 				clr.it_interval.tv_usec = 0;
4267c478bd9Sstevel@tonic-gate 				if (clr.it_value.tv_sec < 0)
4277c478bd9Sstevel@tonic-gate 					clr.it_value.tv_sec = 0;
4287c478bd9Sstevel@tonic-gate 				if (clr.it_value.tv_sec == 0 &&
4297c478bd9Sstevel@tonic-gate 				    clr.it_value.tv_usec == 0)
4307c478bd9Sstevel@tonic-gate 					clr.it_value.tv_usec = 1000;
4317c478bd9Sstevel@tonic-gate 				(void) setitimer(ITIMER_REAL, &clr, NULL);
4327c478bd9Sstevel@tonic-gate 			}
4337c478bd9Sstevel@tonic-gate 			else
4347c478bd9Sstevel@tonic-gate 			{
4357c478bd9Sstevel@tonic-gate 				clr.it_interval.tv_sec = 0;
4367c478bd9Sstevel@tonic-gate 				clr.it_interval.tv_usec = 0;
4377c478bd9Sstevel@tonic-gate 				clr.it_value.tv_sec = 3;
4387c478bd9Sstevel@tonic-gate 				clr.it_value.tv_usec = 0;
4397c478bd9Sstevel@tonic-gate 				(void) setitimer(ITIMER_REAL, &clr, NULL);
4407c478bd9Sstevel@tonic-gate 			}
4417c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
4427c478bd9Sstevel@tonic-gate 			if (SmEventQueue->ev_time > now)
4437c478bd9Sstevel@tonic-gate 				(void) alarm((unsigned) (SmEventQueue->ev_time
4447c478bd9Sstevel@tonic-gate 							 - now));
4457c478bd9Sstevel@tonic-gate 			else
4467c478bd9Sstevel@tonic-gate 				(void) alarm(3);
4477c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
4487c478bd9Sstevel@tonic-gate 		}
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 		/* call ev_func */
4517c478bd9Sstevel@tonic-gate 		errno = save_errno;
4527c478bd9Sstevel@tonic-gate 		(*f)(arg);
4537c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
4547c478bd9Sstevel@tonic-gate 		clr.it_interval.tv_sec = 0;
4557c478bd9Sstevel@tonic-gate 		clr.it_interval.tv_usec = 0;
4567c478bd9Sstevel@tonic-gate 		clr.it_value.tv_sec = 0;
4577c478bd9Sstevel@tonic-gate 		clr.it_value.tv_usec = 0;
4587c478bd9Sstevel@tonic-gate 		(void) setitimer(ITIMER_REAL, &clr, NULL);
4597c478bd9Sstevel@tonic-gate 		gettimeofday(&now, NULL);
4607c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
4617c478bd9Sstevel@tonic-gate 		(void) alarm(0);
4627c478bd9Sstevel@tonic-gate 		now = time(NULL);
4637c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
4647c478bd9Sstevel@tonic-gate 	}
4657c478bd9Sstevel@tonic-gate 	if (SmEventQueue != NULL)
4667c478bd9Sstevel@tonic-gate 	{
4677c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
4687c478bd9Sstevel@tonic-gate 		timersub(&SmEventQueue->ev_time, &now, &clr.it_value);
4697c478bd9Sstevel@tonic-gate 		clr.it_interval.tv_sec = 0;
4707c478bd9Sstevel@tonic-gate 		clr.it_interval.tv_usec = 0;
4717c478bd9Sstevel@tonic-gate 		if (clr.it_value.tv_sec < 0)
4727c478bd9Sstevel@tonic-gate 			clr.it_value.tv_sec = 0;
4737c478bd9Sstevel@tonic-gate 		if (clr.it_value.tv_sec == 0 && clr.it_value.tv_usec == 0)
4747c478bd9Sstevel@tonic-gate 			clr.it_value.tv_usec = 1000;
4757c478bd9Sstevel@tonic-gate 		(void) setitimer(ITIMER_REAL, &clr, NULL);
4767c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
4777c478bd9Sstevel@tonic-gate 		(void) alarm((unsigned) (SmEventQueue->ev_time - now));
4787c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
4797c478bd9Sstevel@tonic-gate 	}
4807c478bd9Sstevel@tonic-gate 	errno = save_errno;
4817c478bd9Sstevel@tonic-gate 	return SIGFUNC_RETURN;
4827c478bd9Sstevel@tonic-gate }
4837c478bd9Sstevel@tonic-gate /*
4847c478bd9Sstevel@tonic-gate **  SLEEP -- a version of sleep that works with this stuff
4857c478bd9Sstevel@tonic-gate **
4867c478bd9Sstevel@tonic-gate **	Because Unix sleep uses the alarm facility, I must reimplement
4877c478bd9Sstevel@tonic-gate **	it here.
4887c478bd9Sstevel@tonic-gate **
4897c478bd9Sstevel@tonic-gate **	Parameters:
4907c478bd9Sstevel@tonic-gate **		intvl -- time to sleep.
4917c478bd9Sstevel@tonic-gate **
4927c478bd9Sstevel@tonic-gate **	Returns:
4937c478bd9Sstevel@tonic-gate **		zero.
4947c478bd9Sstevel@tonic-gate **
4957c478bd9Sstevel@tonic-gate **	Side Effects:
4967c478bd9Sstevel@tonic-gate **		waits for intvl time.  However, other events can
4977c478bd9Sstevel@tonic-gate **		be run during that interval.
4987c478bd9Sstevel@tonic-gate */
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate # if !HAVE_NANOSLEEP
5027c478bd9Sstevel@tonic-gate static void	sm_endsleep __P((int));
5037c478bd9Sstevel@tonic-gate static bool	volatile SmSleepDone;
5047c478bd9Sstevel@tonic-gate # endif /* !HAVE_NANOSLEEP */
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate #ifndef SLEEP_T
5077c478bd9Sstevel@tonic-gate # define SLEEP_T	unsigned int
5087c478bd9Sstevel@tonic-gate #endif /* ! SLEEP_T */
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate SLEEP_T
sleep(intvl)5117c478bd9Sstevel@tonic-gate sleep(intvl)
5127c478bd9Sstevel@tonic-gate 	unsigned int intvl;
5137c478bd9Sstevel@tonic-gate {
5147c478bd9Sstevel@tonic-gate #if HAVE_NANOSLEEP
5157c478bd9Sstevel@tonic-gate 	struct timespec rqtp;
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	if (intvl == 0)
5187c478bd9Sstevel@tonic-gate 		return (SLEEP_T) 0;
5197c478bd9Sstevel@tonic-gate 	rqtp.tv_sec = intvl;
5207c478bd9Sstevel@tonic-gate 	rqtp.tv_nsec = 0;
5217c478bd9Sstevel@tonic-gate 	nanosleep(&rqtp, NULL);
5227c478bd9Sstevel@tonic-gate 	return (SLEEP_T) 0;
5237c478bd9Sstevel@tonic-gate #else /* HAVE_NANOSLEEP */
5247c478bd9Sstevel@tonic-gate 	int was_held;
5257c478bd9Sstevel@tonic-gate 	SM_EVENT *ev;
5267c478bd9Sstevel@tonic-gate #if _FFR_SLEEP_USE_SELECT > 0
5277c478bd9Sstevel@tonic-gate 	int r;
5287c478bd9Sstevel@tonic-gate # if _FFR_SLEEP_USE_SELECT > 0
5297c478bd9Sstevel@tonic-gate 	struct timeval sm_io_to;
5307c478bd9Sstevel@tonic-gate # endif /* _FFR_SLEEP_USE_SELECT > 0 */
5317c478bd9Sstevel@tonic-gate #endif /* _FFR_SLEEP_USE_SELECT > 0 */
5327c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
5337c478bd9Sstevel@tonic-gate 	struct timeval now, begin, diff;
5347c478bd9Sstevel@tonic-gate # if _FFR_SLEEP_USE_SELECT > 0
5357c478bd9Sstevel@tonic-gate 	struct timeval slpv;
5367c478bd9Sstevel@tonic-gate # endif /* _FFR_SLEEP_USE_SELECT > 0 */
5377c478bd9Sstevel@tonic-gate #else /*  SM_CONF_SETITIMER */
5387c478bd9Sstevel@tonic-gate 	time_t begin, now;
5397c478bd9Sstevel@tonic-gate #endif /*  SM_CONF_SETITIMER */
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 	if (intvl == 0)
5427c478bd9Sstevel@tonic-gate 		return (SLEEP_T) 0;
5437c478bd9Sstevel@tonic-gate #if defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2
5447c478bd9Sstevel@tonic-gate 	if (intvl > _FFR_MAX_SLEEP_TIME)
5457c478bd9Sstevel@tonic-gate 	{
5467c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, "sleep: interval=%u exceeds max value %d",
5477c478bd9Sstevel@tonic-gate 			intvl, _FFR_MAX_SLEEP_TIME);
5487c478bd9Sstevel@tonic-gate # if 0
5497c478bd9Sstevel@tonic-gate 		SM_ASSERT(intvl < (unsigned int) INT_MAX);
5507c478bd9Sstevel@tonic-gate # endif /* 0 */
5517c478bd9Sstevel@tonic-gate 		intvl = _FFR_MAX_SLEEP_TIME;
5527c478bd9Sstevel@tonic-gate 	}
5537c478bd9Sstevel@tonic-gate #endif /* defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 */
5547c478bd9Sstevel@tonic-gate 	SmSleepDone = false;
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
5577c478bd9Sstevel@tonic-gate # if _FFR_SLEEP_USE_SELECT > 0
5587c478bd9Sstevel@tonic-gate 	slpv.tv_sec = intvl;
5597c478bd9Sstevel@tonic-gate 	slpv.tv_usec = 0;
5607c478bd9Sstevel@tonic-gate # endif /* _FFR_SLEEP_USE_SELECT > 0 */
5617c478bd9Sstevel@tonic-gate 	(void) gettimeofday(&now, NULL);
5627c478bd9Sstevel@tonic-gate 	begin = now;
5637c478bd9Sstevel@tonic-gate #else /*  SM_CONF_SETITIMER */
5647c478bd9Sstevel@tonic-gate 	now = begin = time(NULL);
5657c478bd9Sstevel@tonic-gate #endif /*  SM_CONF_SETITIMER */
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	ev = sm_setevent((time_t) intvl, sm_endsleep, 0);
5687c478bd9Sstevel@tonic-gate 	if (ev == NULL)
5697c478bd9Sstevel@tonic-gate 	{
5707c478bd9Sstevel@tonic-gate 		/* COMPLAIN */
5717c478bd9Sstevel@tonic-gate #if 0
5727c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, "sleep: sm_setevent(%u) failed", intvl);
5737c478bd9Sstevel@tonic-gate #endif /* 0 */
5747c478bd9Sstevel@tonic-gate 		SmSleepDone = true;
5757c478bd9Sstevel@tonic-gate 	}
5767c478bd9Sstevel@tonic-gate 	was_held = sm_releasesignal(SIGALRM);
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 	while (!SmSleepDone)
5797c478bd9Sstevel@tonic-gate 	{
5807c478bd9Sstevel@tonic-gate #if SM_CONF_SETITIMER
5817c478bd9Sstevel@tonic-gate 		(void) gettimeofday(&now, NULL);
5827c478bd9Sstevel@tonic-gate 		timersub(&now, &begin, &diff);
5837c478bd9Sstevel@tonic-gate 		if (diff.tv_sec < 0 ||
5847c478bd9Sstevel@tonic-gate 		    (diff.tv_sec == 0 && diff.tv_usec == 0))
5857c478bd9Sstevel@tonic-gate 			break;
5867c478bd9Sstevel@tonic-gate # if _FFR_SLEEP_USE_SELECT > 0
5877c478bd9Sstevel@tonic-gate 		timersub(&slpv, &diff, &sm_io_to);
5887c478bd9Sstevel@tonic-gate # endif /* _FFR_SLEEP_USE_SELECT > 0 */
5897c478bd9Sstevel@tonic-gate #else /* SM_CONF_SETITIMER */
5907c478bd9Sstevel@tonic-gate 		now = time(NULL);
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate 		/*
5937c478bd9Sstevel@tonic-gate 		**  Check whether time expired before signal is released.
5947c478bd9Sstevel@tonic-gate 		**  Due to the granularity of time() add 1 to be on the
5957c478bd9Sstevel@tonic-gate 		**  safe side.
5967c478bd9Sstevel@tonic-gate 		*/
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate 		if (!(begin + (time_t) intvl + 1 > now))
5997c478bd9Sstevel@tonic-gate 			break;
6007c478bd9Sstevel@tonic-gate # if _FFR_SLEEP_USE_SELECT > 0
6017c478bd9Sstevel@tonic-gate 		sm_io_to.tv_sec = intvl - (now - begin);
6027c478bd9Sstevel@tonic-gate 		if (sm_io_to.tv_sec <= 0)
6037c478bd9Sstevel@tonic-gate 			sm_io_to.tv_sec = 1;
6047c478bd9Sstevel@tonic-gate 		sm_io_to.tv_usec = 0;
6057c478bd9Sstevel@tonic-gate # endif /* _FFR_SLEEP_USE_SELECT > 0 */
6067c478bd9Sstevel@tonic-gate #endif /* SM_CONF_SETITIMER */
6077c478bd9Sstevel@tonic-gate #if _FFR_SLEEP_USE_SELECT > 0
6087c478bd9Sstevel@tonic-gate 		if (intvl <= _FFR_SLEEP_USE_SELECT)
6097c478bd9Sstevel@tonic-gate 		{
6107c478bd9Sstevel@tonic-gate 			r = select(0, NULL, NULL, NULL, &sm_io_to);
6117c478bd9Sstevel@tonic-gate 			if (r == 0)
6127c478bd9Sstevel@tonic-gate 				break;
6137c478bd9Sstevel@tonic-gate 		}
6147c478bd9Sstevel@tonic-gate 		else
6157c478bd9Sstevel@tonic-gate #endif /* _FFR_SLEEP_USE_SELECT > 0 */
6167c478bd9Sstevel@tonic-gate 		(void) pause();
6177c478bd9Sstevel@tonic-gate 	}
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 	/* if out of the loop without the event being triggered remove it */
6207c478bd9Sstevel@tonic-gate 	if (!SmSleepDone)
6217c478bd9Sstevel@tonic-gate 		sm_clrevent(ev);
6227c478bd9Sstevel@tonic-gate 	if (was_held > 0)
6237c478bd9Sstevel@tonic-gate 		(void) sm_blocksignal(SIGALRM);
6247c478bd9Sstevel@tonic-gate 	return (SLEEP_T) 0;
6257c478bd9Sstevel@tonic-gate #endif /* HAVE_NANOSLEEP */
6267c478bd9Sstevel@tonic-gate }
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate #if !HAVE_NANOSLEEP
6297c478bd9Sstevel@tonic-gate static void
sm_endsleep(ignore)6307c478bd9Sstevel@tonic-gate sm_endsleep(ignore)
6317c478bd9Sstevel@tonic-gate 	int ignore;
6327c478bd9Sstevel@tonic-gate {
6337c478bd9Sstevel@tonic-gate 	/*
6347c478bd9Sstevel@tonic-gate 	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
6357c478bd9Sstevel@tonic-gate 	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
6367c478bd9Sstevel@tonic-gate 	**	DOING.
6377c478bd9Sstevel@tonic-gate 	*/
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 	SmSleepDone = true;
6407c478bd9Sstevel@tonic-gate }
6417c478bd9Sstevel@tonic-gate #endif /* !HAVE_NANOSLEEP */
6427c478bd9Sstevel@tonic-gate 
643