File: shutdown.c

package info (click to toggle)
doodle 0.7.0-5
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 2,652 kB
  • sloc: sh: 10,841; ansic: 7,793; java: 152; makefile: 138; sed: 16
file content (141 lines) | stat: -rw-r--r-- 3,287 bytes parent folder | download | duplicates (7)
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 */