/*
 * libnqs/misc/nqssleep.c
 * 
 * DESCRIPTION:
 *
 *	NQS version of sleep().  The System V one has a very nasty
 *	bug such that when a non-SIGALRM signal arrives which is to
 *	be caught, AND the SIGALRM signal just happens to arrive
 *	while handling the first signal, then we never return to
 *	the original signal handler.
 *
 *	Thank you again AT&T.  The mighty mountain has labored, and
 *	once again failed to even produce a mouse correctly.
 *
 *	Original Author:
 *	-------
 *	Brent A. Kingsbury, Sterling Software Incorporated.
 *	August 12, 1985.
 */

#include <libnqs/license.h>
#include <libnqs/proto.h>
#include <signal.h>
#include <unistd.h>

static void alarmsig ( int );

/*
 *
 *
 *	Variables local to this module.
 */
static short alarm_semaphore;		/* SIGALRM semaphore */


/*** nqssleep
 *
 *
 *	nqssleep():
 *	Sleep for N seconds.
 */
void nqssleep (int timetosleep)
{
	void (*sigalrm_sav)(int);		/* Save old SIGALRM handler */
	unsigned origalarm;		/* Original alarm time */

	origalarm = alarm (0);		/* Get original alarm set */
	sigalrm_sav = signal (SIGALRM, alarmsig); /* Get/Set SIGALRM handler */
	alarm_semaphore = 0;		/* Clear SIGALRM semaphore */
	alarm (timetosleep);		/* Set the alarm */
	while (alarm_semaphore == 0) pause();
	signal (SIGALRM, sigalrm_sav);	/* Restore SIGALRM state */
	alarm (origalarm);		/* Restore the original alarm */
}


/*** alarmsig
 *
 *
 *	void alarmsig():
 *
 *	This function serves as the signal catcher for SIGARLM signals
 *	occuring as the result of an alarm () call in the return_file()
 *	function above.
 *
 *	This function SETS the "alarm_semphore" flag.
 */
static void alarmsig ( int unused )
{
	signal (SIGALRM, alarmsig);
	alarm_semaphore++;		/* SIGALRM received */
}
