/*
 * nqs_generic/all-systems/nqssleep.c
 * Virtual alarm support
 */

#include <nqs_generic/license.h>
  /* NQS license information */
#include <nqs_generic/debug.h>
  /* debugging support */
#include <nqs_generic/proto.h>
  /* ANSI C prototypes */

/*++ nqssleep.c - Network Queueing System
 *
 * $Source: /usr2/jrroma/nqs/nqs-3.30/lib/RCS/nqssleep.c,v $
 *
 * 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.
 *
 *
 *	Author:
 *	-------
 *	Brent A. Kingsbury, Sterling Software Incorporated.
 *	August 12, 1985.
 */

#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 */

  ENTER_FUNCTION("nqs_generic/all-systems/nqssleep");
    /* debugging information */
  DEBUGGING(INFO, DEBUG_LOW, "This routine has not been POSIX'ised yet\n");
    /* NQS becomes nagware ... */
  
  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 */
  
  EXIT_FUNCTION;
}

/*** 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 iDummy)
{
  ENTER_FUNCTION("nqs_generic/all-sytems/alarmsig");
    /* debugging support */
  DEBUGGING(INFO,DEBUG_LOW,"This routine uses non POSIX signalling.\n");
    /* NAGware NQS ;-) */
  signal (SIGALRM, alarmsig);
  alarm_semaphore++;		/* SIGALRM received */
  EXIT_FUNCTION;
}
