/* * This file is part of rasdaman community. * * Rasdaman community is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rasdaman community is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rasdaman community. If not, see . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . */ /*------------------------------------------------------------------------*/ /* signals.c - signal handling stuff. */ /*------------------------------------------------------------------------*/ /* * RCS: * $RCSfile: signals.c,v $ $Revision: 1.8 $ $State: Exp $ * $Locker: $ */ #include "defs.h" #include "protos.h" #include "server.h" extern struct ServerBase Server; /****** signals/Signal ******************************************************* * * NAME * * * SYNOPSIS * * * FUNCTION * * * INPUTS * * * RESULT * * * NOTES * Own Signal() function, based on sigaction(). * * BUGS * * * SEE ALSO * * ****************************************************************************** * */ sighandler Signal( int signo, sighandler x) { struct sigaction SigAction; struct sigaction OldAction; SigAction.sa_handler = (void(*)(int))SigHandler; sigemptyset( & SigAction.sa_mask ); SigAction.sa_flags = 0; if( signo == SIGALRM ) { #ifdef SA_INTERRUPT SigAction.sa_flags |= SA_INTERRUPT; /* SunOS */ #endif } else { #ifdef SA_RESTART SigAction.sa_flags |= SA_RESTART; /* SVR4, 4.3+ BSD */ #endif } if( sigaction( signo, &SigAction, &OldAction ) < 0 ) return( SIG_ERR ); return( OldAction.sa_handler ); } /****** signals/SigHandler *************************************************** * * NAME * SigHandler -- Little Signal Handler. * * SYNOPSIS * * * FUNCTION * * * INPUTS * * * RESULT * * * NOTES * * * BUGS * * * SEE ALSO * * ****************************************************************************** * */ void SigHandler( int Signal ) { //not used(see line 169) char Buffer[PIPE_BUFFSIZE]; int errno_bak; int ChildStatus; pid_t ChildPId; struct ChildBase *Child = NULL; errno_bak = errno; switch( Signal ) { case SIGHUP: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGHUP'." ); errno = errno_bak; Exit( OK ); break; case SIGINT: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGINT'." ); errno = errno_bak; Exit( OK ); break; case SIGQUIT: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGQUIT'." ); errno = errno_bak; Exit( OK ); break; case SIGUSR1: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGUSR1'." ); // SaveCache( Server.Cache, Server.CacheFile ); break; case SIGUSR2: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGUSR2'." ); break; case SIGPIPE: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGPIPE'." ); break; case SIGTERM: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGTERM'." ); errno = errno_bak; Exit( OK ); break; case SIGCHLD: LogMsg( LG_SERVER, INFO, "INFO: Received 'SIGCHLD'." ); ChildPId = waitpid( -1, &ChildStatus, WNOHANG ); while( ChildPId > 0 ) { if( WIFEXITED( ChildStatus ) ) { /*-- Has Child send a Message? --*/ if( WEXITSTATUS( ChildStatus ) == NOTE ) { Child = GetChild( Server.ChildList, ChildPId ); if( Child != NULL ) { /* bzero( Buffer, PIPE_BUFFSIZE ); read( Child->PD[0], Buffer, PIPE_BUFFSIZE ); HandlePipeMsg( Buffer, Server.SubServerList, Server.Cache ); */ } } LogMsg( LG_SERVER, DEBUG, "DEBUG: Child <%d> exited normally with status %d.", ChildPId, WEXITSTATUS( ChildStatus ) ); } else if( WIFSIGNALED( ChildStatus ) ) { LogMsg( LG_SERVER, DEBUG, "DEBUG: Child <%d> exited abnormally, signal number = %d.", ChildPId, WTERMSIG( ChildStatus ) ); } else if( WIFSTOPPED( ChildStatus ) ) { LogMsg( LG_SERVER, DEBUG, "DEBUG: Child <%d> is stopped, signal number = %d.", ChildPId, WSTOPSIG( ChildStatus ) ); } else { LogMsg( LG_SERVER, WARN, "WARN: Something strange with Child <%d> (Status: %d).", ChildPId, ChildStatus ); } CleanupChild( Server.ChildList, &Server.PipeSets, ChildPId ); ChildPId = waitpid( -1, &ChildStatus, WNOHANG ); } if( ChildPId == -1 && errno != ECHILD ) ErrorMsg( E_SYS, WARN, "WARN: waitpid() returned an Error.", errno ); LogMsg( LG_SERVER, DEBUG, "DEBUG: Exiting Signal Handler ..." ); break; default: ErrorMsg( E_PRIV, ERROR, "ERROR: Signal %d couldn't be handled!", Signal ); break; } errno = errno_bak; return; } /****** signals/InitSigHandler *********************************************** * * NAME * InitSigHandler -- Minimum Signal Handler setup. * * SYNOPSIS * * * FUNCTION * * * INPUTS * * * RESULT * * * NOTES * * * BUGS * * * SEE ALSO * * ****************************************************************************** * */ rc_t InitSigHandler( void ) { if( Signal( SIGHUP, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (HUP)." ); if( Signal( SIGINT, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (INT)." ); if( Signal( SIGQUIT, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (QUIT)." ); if( Signal( SIGTERM, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (TERM)." ); if( Signal( SIGCHLD, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (CHLD)." ); if( Signal( SIGUSR1, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (USR1)." ); if( Signal( SIGUSR2, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (USR2)." ); if( Signal( SIGPIPE, SigHandler ) == SIG_ERR ) ErrorMsg( E_SYS, ERROR, "ERROR: Installing Signal Handler (PIPE)." ); return( OK ); }