Freeciv-3.2: /fast/freeciv/nightly/S3_2/server/srv_signal.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
srv_signal.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include "fc_prehdrs.h"
19
20#ifdef HAVE_UNISTD_H
21#include <unistd.h>
22#endif
23
24#ifdef HAVE_SIGNAL_H
25#include <signal.h>
26#endif
27
28/* utility */
29#include "fciconv.h"
30#include "log.h"
31#include "timing.h"
32
33/* server */
34#include "srv_main.h"
35
36/* server/savegame */
37#include "savemain.h"
38
39#include "srv_signal.h"
40
41#ifdef HAVE_SIGNAL_H
42#define USE_INTERRUPT_HANDLERS
43#endif
44
45#ifdef USE_INTERRUPT_HANDLERS
46#define save_and_exit(sig) \
47if (S_S_RUNNING == server_state()) { \
48 save_game_auto(#sig, AS_INTERRUPT); \
49 save_system_close(); \
50} \
51exit(EXIT_SUCCESS);
52
53static struct timer *signal_timer = NULL;
54
55/**********************************************************************/
59static void signal_handler(int sig)
60{
61 switch (sig) {
62 case SIGINT:
63 if (signal_timer != NULL && timer_read_seconds(signal_timer) <= 1.0) {
64 save_and_exit(SIGINT);
65 } else {
66 if (game.info.timeout == -1) {
67 log_normal(_("Setting timeout to 0. Autogame will stop."));
68 game.info.timeout = 0;
69 }
70 if (signal_timer == NULL) {
71 log_normal(_("You must interrupt Freeciv twice "
72 "within one second to make it exit."));
73 }
74 }
75 signal_timer = timer_renew(signal_timer, TIMER_USER, TIMER_ACTIVE,
76 signal_timer != NULL ? NULL : "ctrlc");
77 timer_start(signal_timer);
78 break;
79
80#ifdef SIGHUP
81 case SIGHUP:
82 save_and_exit(SIGHUP);
83 break;
84#endif /* SIGHUP */
85
86 case SIGTERM:
87 save_and_exit(SIGTERM);
88 break;
89
90#ifdef SIGPIPE
91 case SIGPIPE:
92 if (signal(SIGPIPE, signal_handler) == SIG_ERR) {
93 /* Because the signal may have interrupted arbitrary code, we use
94 * fprintf() and _exit() here instead of log_*() and exit() so
95 * that we don't accidentally call any "unsafe" functions here
96 * (see the manual page for the signal function). */
97 fprintf(stderr, "\nFailed to reset SIGPIPE handler "
98 "while handling SIGPIPE.\n");
99 _exit(EXIT_FAILURE);
100 }
101 break;
102#endif /* SIGPIPE */
103 }
104}
105
106#endif /* USE_INTERRUPT_HANDLERS */
107
108/**********************************************************************/
111 void setup_interrupt_handlers(void)
112{
113#ifdef USE_INTERRUPT_HANDLERS
114 if (SIG_ERR == signal(SIGINT, signal_handler)) {
115 fc_fprintf(stderr, _("Failed to install SIGINT handler: %s\n"),
116 fc_strerror(fc_get_errno()));
117 exit(EXIT_FAILURE);
118 }
119
120#ifdef SIGHUP
121 if (SIG_ERR == signal(SIGHUP, signal_handler)) {
122 fc_fprintf(stderr, _("Failed to install SIGHUP handler: %s\n"),
123 fc_strerror(fc_get_errno()));
124 exit(EXIT_FAILURE);
125 }
126#endif /* SIGHUP */
127
128 if (SIG_ERR == signal(SIGTERM, signal_handler)) {
129 fc_fprintf(stderr, _("Failed to install SIGTERM handler: %s\n"),
130 fc_strerror(fc_get_errno()));
131 exit(EXIT_FAILURE);
132 }
133
134#ifdef SIGPIPE
135 /* Ignore SIGPIPE, the error is handled by the return value
136 * of the write call. */
137 if (SIG_ERR == signal(SIGPIPE, signal_handler)) {
138 fc_fprintf(stderr, _("Failed to ignore SIGPIPE: %s\n"),
139 fc_strerror(fc_get_errno()));
140 exit(EXIT_FAILURE);
141 }
142#endif /* SIGPIPE */
143#endif /* USE_INTERRUPT_HANDLERS */
144}
145
146/**********************************************************************/
149 void signal_timer_free(void)
150{
151 if (signal_timer != NULL) {
152 timer_destroy(signal_timer);
153 signal_timer = NULL;
154 }
155}
incite_cost
char * incite_cost
Definition comments.c:74
fc_prehdrs.h
fciconv.h
fc_fprintf
void fc_fprintf(FILE *stream, const char *format,...) fc__attribute((__format__(__printf__
_
#define _(String)
Definition fcintl.h:67
game
struct civ_game game
Definition game.c:62
log.h
log_normal
#define log_normal(message,...)
Definition log.h:107
savemain.h
srv_main.h
setup_interrupt_handlers
void setup_interrupt_handlers(void)
Definition srv_signal.c:111
signal_timer_free
void signal_timer_free(void)
Definition srv_signal.c:149
srv_signal.h
civ_game::info
struct packet_game_info info
Definition game.h:89
packet_game_info::timeout
int timeout
Definition packets_gen.h:233
signal
Definition luascript_signal.c:75
timer
Definition timing.c:81
fc_strerror
const char * fc_strerror(fc_errno err)
Definition support.c:611
fc_get_errno
fc_errno fc_get_errno(void)
Definition support.c:594
timer_destroy
void timer_destroy(struct timer *t)
Definition timing.c:208
timer_start
void timer_start(struct timer *t)
Definition timing.c:264
timer_read_seconds
double timer_read_seconds(struct timer *t)
Definition timing.c:384
timer_renew
struct timer * timer_renew(struct timer *t, enum timer_timetype type, enum timer_use use, const char *name)
Definition timing.c:180
timing.h
TIMER_ACTIVE
@ TIMER_ACTIVE
Definition timing.h:46
TIMER_USER
@ TIMER_USER
Definition timing.h:42