1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
This file is part of doodle.
(C) 2001, 2002 Christian Grothoff (and other contributing authors)
doodle 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 2, or (at your
option) any later version.
doodle 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 doodle; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* @file doodle/shutdown.c
* @brief code to allow clean shutdown of application with signals
* @author Christian Grothoff
*
* Helper code for writing proper termination code when an application
* receives a SIGTERM/SIGHUP etc.
*/
#include "config.h"
#include "semaphore.h"
#include "shutdown.h"
#include <signal.h>
#include "gettext.h"
/**
* Semaphore used to signal "shutdown"
*/
static Semaphore * shutdown_signal = NULL;
static int shutdown_active;
/**
* Stop the application.
* @param signum is ignored
*/
void run_shutdown(int signum) {
if (shutdown_signal != NULL) {
shutdown_active = 1;
SEMAPHORE_UP(shutdown_signal);
}
}
/**
* Stop the application under Windows.
* @param signum is ignored
*/
#ifdef MINGW
BOOL WINAPI run_shutdown_win(DWORD dwCtrlType)
{
switch(dwCtrlType)
{
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_SHUTDOWN_EVENT:
case CTRL_LOGOFF_EVENT:
run_shutdown(1);
}
return TRUE;
}
#endif
/**
* Test if the shutdown has been initiated.
* @return 1 if we are shutting down, 0 otherwise
*/
int testShutdown() {
return shutdown_active;
}
/**
* Initialize the signal handlers, etc.
*/
void initializeShutdownHandlers() {
#ifndef MINGW
struct sigaction sig;
struct sigaction oldsig;
#endif
if (shutdown_signal != NULL)
abort(); /* initializeShutdownHandlers called twice! */
shutdown_signal = SEMAPHORE_NEW(0);
shutdown_active = 0;
#ifndef MINGW
sig.sa_handler = &run_shutdown;
sigemptyset(&sig.sa_mask);
#ifdef SA_INTERRUPT
sig.sa_flags = SA_INTERRUPT; /* SunOS */
#else
sig.sa_flags = SA_RESTART;
#endif
sigaction(SIGINT, &sig, &oldsig);
sigaction(SIGTERM, &sig, &oldsig);
sigaction(SIGQUIT, &sig, &oldsig);
#else
SetConsoleCtrlHandler(&run_shutdown_win, TRUE);
#endif
}
/**
* Wait until the shutdown has been initiated.
*/
void wait_for_shutdown() {
SEMAPHORE_DOWN(shutdown_signal);
}
void doneShutdownHandlers() {
#ifndef MINGW
struct sigaction sig;
struct sigaction oldsig;
sig.sa_handler = SIG_DFL;
sigemptyset(&sig.sa_mask);
#ifdef SA_INTERRUPT
sig.sa_flags = SA_INTERRUPT; /* SunOS */
#else
sig.sa_flags = SA_RESTART;
#endif
sigaction(SIGINT, &sig, &oldsig);
sigaction(SIGTERM, &sig, &oldsig);
sigaction(SIGQUIT, &sig, &oldsig);
#else
SetConsoleCtrlHandler(&run_shutdown_win, FALSE);
#endif
SEMAPHORE_FREE(shutdown_signal);
shutdown_signal = NULL;
}
/* end of shutdown.c */
|