/*
 * File :       hgsignal.C
 *
 * Purpose :    Hyper-G Signal Handling
 *
 * Created :    07 May 92    Keith Andrews, IICM
 *
 * Modified :   07 May 92    Keith Andrews, IICM
 *
 */


#include "hgsignal.h"

#ifndef OSF1
#  if !defined(hpux) && !defined(UnixWare)
#    include <osfcn.h>
#  endif
#endif

#include <iostream.h>
#include <stdlib.h>

#include <hyperg/utils/hgunistd.h>

/*
 * static void cleanup( int i )
 *
 * Cleans up everything and output error message.
 * Called when a signal (eg. ^C) has been caught.
 *
 */

static void cleanup( int i )
{
  cerr << "Program stopped (caught signal " << i << ")" << endl ;
  exit( i ) ;
}



#ifdef ULTRIX
/*
 * static void wait_for_child( int )
 *
 */

static void wait_for_child( int )
{
//   int pid ;
//   union wait status ;
//   static int options = WNOHANG ;
//   struct rusage rusage ;

//   cerr << "wait_for_child: got SIGCLD" << endl ;

//   if ( (pid = wait3(&status, options, &rusage)) <= 0 )
//     cerr << "wait3 failed: pid=" << pid << endl ;

// gpani (94/07/07)
     pid_t pid;
     static int options = WNOHANG;
     int status_location;
     pid_t wanted = -1;

     cerr << "wait_for_child: got SIGCHLD" << endl;

     while ((pid = waitpid( wanted, &status_location, options)) > 0 );
     
     if (pid == -1)
	  perror( "wait_for_child: waitpid");

}
#endif


// gpani (95/01/12)

// void hg_signals()
// {
// #ifdef ULTRIX
//   signal( SIGSEGV, cleanup ) ;
//   signal( SIGINT, cleanup ) ;
//   signal( SIGKILL, cleanup ) ;
//   signal( SIGHUP, cleanup ) ;
//   signal( SIGTERM, cleanup ) ;
//   signal( SIGILL, cleanup ) ;
//   if ( signal( SIGCLD, wait_for_child ) == BADSIG )     // ignore death of child to avoid zombie processes
//     cerr << "ignoring SIGCLD failed" << endl ;
// #else
// #if defined(SUN) && HG_OSMaj >= 5
//   signal( SIGSEGV, cleanup ) ;
//   signal( SIGINT, cleanup ) ;
//   signal( SIGKILL, cleanup ) ;
//   signal( SIGHUP, cleanup ) ;
//   signal( SIGTERM, cleanup ) ;
//   signal( SIGILL, cleanup ) ;
//   if ( signal( SIGCLD, SIG_IGN ) == SIG_ERR )
//     cerr << "ignoring SIGCLD failed" << endl ;
// #else
// #ifdef SYSV
//   signal( SIGSEGV, (void(*)(int ...))cleanup ) ;
//   signal( SIGINT, (void(*)(int ...))cleanup ) ;
//   signal( SIGKILL, (void(*)(int ...))cleanup ) ;
//   signal( SIGHUP, (void(*)(int ...))cleanup ) ;
//   signal( SIGTERM, (void(*)(int ...))cleanup ) ;
//   signal( SIGILL, (void(*)(int ...))cleanup ) ;
// #ifdef IRIX
//   if ( signal( SIGCLD, SIG_IGN ) == (void(*)(...))-1 )
// #else
//   if ( signal( SIGCLD, SIG_IGN ) == (void(*)(int ))-1 )
// #endif
//     cerr << "ignoring SIGCLD failed" << endl ;
// #else
//   signal( SIGSEGV, cleanup ) ;
//   signal( SIGINT, cleanup ) ;
//   signal( SIGKILL, cleanup ) ;
//   signal( SIGHUP, cleanup ) ;
//   signal( SIGTERM, cleanup ) ;
//   signal( SIGILL, cleanup ) ;
//   if ( signal( SIGCLD, SIG_IGN ) == BADSIG )
//     cerr << "ignoring SIGCLD failed" << endl ;
// #endif
// #endif
// #endif
// }

void hg_signals()
{
  hg_signal( SIGSEGV, cleanup ) ;
  hg_signal( SIGINT, cleanup ) ;
  hg_signal( SIGKILL, cleanup ) ;
  hg_signal( SIGHUP, cleanup ) ;
  hg_signal( SIGTERM, cleanup ) ;
  hg_signal( SIGILL, cleanup ) ;
#ifdef ULTRIX
  if ( hg_signal( SIGCHLD, wait_for_child ) == SIG_ERR )   // ignore death of child to avoid zombie processes
       cerr << "ignoring SIGCHLD failed" << endl ;
#else
  if ( hg_signal( SIGCHLD, (Sigfunc*)SIG_IGN ) == (Sigfunc*)SIG_ERR )
       cerr << "ignoring SIGCHLD failed" << endl ;
#endif
}
