blob: bc54b4f79e773bd884e75ef357a6ebfa668ca440 [file] [log] [blame] [edit]
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) and associated
* documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* signal.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* standard signal installer
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
/* list of signal handlers. _NSIG is number of signals defined. */
static SigfuncPtr handlers[ _NSIG ] = { 0};
/* -------------------------------------------------------------------
* sig_dispatcher
*
* dispatches the signal to appropriate signal handler. This emulates
* the signal handling of Unix.
*
* ------------------------------------------------------------------- */
BOOL WINAPI sig_dispatcher( DWORD type ) {
SigfuncPtr h = NULL;
int signo;
switch ( type ) {
case CTRL_C_EVENT:
signo = SIGINT;
h = handlers[ SIGINT ];
break;
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
signo = SIGTERM;
h = handlers[ SIGTERM ];
break;
default:
break;
}
if ( h != NULL ) {
// call the signal handler
h( signo );
return true;
} else {
return false;
}
}
/* -------------------------------------------------------------------
* my_signal
*
* installs a signal handler. I emulate Unix signals by storing the
* function pointers and dispatching events myself, using the
* sig_dispatcher above.
* ------------------------------------------------------------------- */
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
SigfuncPtr old = NULL;
if ( inSigno >= 0 && inSigno < _NSIG ) {
old = handlers[ inSigno ];
handlers[ inSigno ] = inFunc;
}
return old;
} /* end my_signal */
#else /* not WIN32 */
/* -------------------------------------------------------------------
* my_signal
*
* installs a signal handler, and returns the old handler.
* This emulates the semi-standard signal() function in a
* standard way using the Posix sigaction function.
*
* from Stevens, 1998, section 5.8
* ------------------------------------------------------------------- */
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
struct sigaction theNewAction, theOldAction;
assert( inFunc != NULL );
theNewAction.sa_handler = inFunc;
sigemptyset( &theNewAction.sa_mask );
theNewAction.sa_flags = 0;
if ( inSigno == SIGALRM ) {
#ifdef SA_INTERRUPT
theNewAction.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
theNewAction.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
#endif
}
if ( sigaction( inSigno, &theNewAction, &theOldAction ) < 0 ) {
return SIG_ERR;
} else {
return theOldAction.sa_handler;
}
} /* end my_signal */
#endif /* not WIN32 */
/* -------------------------------------------------------------------
* sig_exit
*
* Quietly exits. This protects some against being called multiple
* times. (TODO: should use a mutex to ensure (num++ == 0) is atomic.)
* ------------------------------------------------------------------- */
void sig_exit( int inSigno ) {
static int num = 0;
if ( num++ == 0 ) {
fflush( 0 );
exit( 0 );
}
} /* end sig_exit */
#ifdef __cplusplus
} /* end extern "C" */
#endif