2 * @file signal-handlers.c
3 * @brief シグナルハンドラの管理 / Controlling signal handlers
8 #include "io/signal-handlers.h"
9 #include "cmd-io/cmd-dump.h"
10 #include "core/game-closer.h"
11 #include "floor/floor-events.h"
12 #include "io/write-diary.h"
13 #include "monster-floor/monster-lite.h"
14 #include "save/save.h"
15 #include "system/system-variables.h"
16 #include "term/term-color-types.h"
17 #include "world/world.h"
19 s16b signal_count; /* Hack -- Count interupts */
24 * @brief OSからのシグナルを受けてサスペンド状態に入る /
25 * Handle signals -- suspend
26 * @param sig 受け取ったシグナル
28 * Actually suspend the game, and then resume cleanly
30 static void handle_signal_suspend(int sig)
32 (void)signal(sig, SIG_IGN);
35 term_xtra(TERM_XTRA_ALIVE, 0);
36 (void)kill(0, SIGSTOP);
37 term_xtra(TERM_XTRA_ALIVE, 1);
41 (void)signal(sig, handle_signal_suspend);
45 * todo ここにplayer_typeを追加すると関数ポインタ周りの収拾がつかなくなるので保留
46 * @brief OSからのシグナルを受けて中断、終了する /
47 * Handle signals -- simple (interrupt and quit)
48 * @param sig 受け取ったシグナル
51 * This function was causing a *huge* number of problems, so it has
52 * been simplified greatly. We keep a global variable which counts
53 * the number of times the user attempts to kill the process, and
54 * we commit suicide if the user does this a certain number of times.
55 * We attempt to give "feedback" to the user as he approaches the
56 * suicide thresh-hold, but without penalizing accidental keypresses.
57 * To prevent messy accidents, we should reset this global variable
58 * whenever the user enters a keypress, or something like that.
61 static void handle_signal_simple(int sig)
63 (void)signal(sig, SIG_IGN);
64 if (!current_world_ptr->character_generated || current_world_ptr->character_saved)
69 (void)strcpy(p_ptr->died_from, _("強制終了", "Abortion"));
70 forget_lite(p_ptr->current_floor_ptr);
71 forget_view(p_ptr->current_floor_ptr);
72 clear_mon_lite(p_ptr->current_floor_ptr);
74 quit(_("強制終了", "interrupt"));
75 } else if (signal_count >= 5) {
76 (void)strcpy(p_ptr->died_from, _("強制終了中", "Interrupting"));
77 forget_lite(p_ptr->current_floor_ptr);
78 forget_view(p_ptr->current_floor_ptr);
79 clear_mon_lite(p_ptr->current_floor_ptr);
80 p_ptr->playing = FALSE;
81 p_ptr->is_dead = TRUE;
82 p_ptr->leaving = TRUE;
84 quit(_("強制終了", "interrupt"));
85 } else if (signal_count >= 4) {
86 term_xtra(TERM_XTRA_NOISE, 0);
87 term_erase(0, 0, 255);
88 term_putstr(0, 0, -1, TERM_WHITE, _("熟慮の上の自殺!", "Contemplating suicide!"));
90 } else if (signal_count >= 2) {
91 term_xtra(TERM_XTRA_NOISE, 0);
94 (void)signal(sig, handle_signal_simple);
98 * todo ここにp_ptrを追加すると関数ポインタ周りの収拾がつかなくなるので保留
99 * @brief OSからのシグナルを受けて強制終了する /
100 * Handle signal -- abort, kill, etc
101 * @param sig 受け取ったシグナル
105 * This function was causing a *huge* number of problems, so it has
106 * been simplified greatly. We keep a global variable which counts
107 * the number of times the user attempts to kill the process, and
108 * we commit suicide if the user does this a certain number of times.
109 * We attempt to give "feedback" to the user as he approaches the
110 * suicide thresh-hold, but without penalizing accidental keypresses.
111 * To prevent messy accidents, we should reset this global variable
112 * whenever the user enters a keypress, or something like that.
115 static void handle_signal_abort(int sig)
118 term_get_size(&wid, &hgt);
120 (void)signal(sig, SIG_IGN);
121 if (!current_world_ptr->character_generated || current_world_ptr->character_saved)
124 forget_lite(p_ptr->current_floor_ptr);
125 forget_view(p_ptr->current_floor_ptr);
126 clear_mon_lite(p_ptr->current_floor_ptr);
128 term_erase(0, hgt - 1, 255);
129 term_putstr(0, hgt - 1, -1, TERM_RED, _("恐ろしいソフトのバグが飛びかかってきた!", "A gruesome software bug LEAPS out at you!"));
131 term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ...", "Panic save..."));
133 exe_write_diary(p_ptr, DIARY_GAMESTART, 0, _("----ゲーム異常終了----", "-- Tried Panic Save and Aborted Game --"));
136 p_ptr->panic_save = 1;
137 (void)strcpy(p_ptr->died_from, _("(緊急セーブ)", "(panic save)"));
139 signals_ignore_tstp();
141 if (save_player(p_ptr)) {
142 term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ成功!", "Panic save succeeded!"));
144 term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ失敗!", "Panic save failed!"));
148 quit(_("ソフトのバグ", "software bug"));
152 * @brief OSからのSIGTSTPシグナルを無視する関数 /
153 * Ignore SIGTSTP signals (keyboard suspend)
157 void signals_ignore_tstp(void)
160 (void)signal(SIGTSTP, SIG_IGN);
165 * @brief OSからのSIGTSTPシグナルハンドラ /
166 * Handle SIGTSTP signals (keyboard suspend)
170 void signals_handle_tstp(void)
173 (void)signal(SIGTSTP, handle_signal_suspend);
178 * @brief OSからのシグナルハンドルを初期化する /
179 * Prepare to handle the relevant signals
183 void signals_init(void)
186 (void)signal(SIGHUP, SIG_IGN);
190 (void)signal(SIGTSTP, handle_signal_suspend);
194 (void)signal(SIGINT, handle_signal_simple);
198 (void)signal(SIGQUIT, handle_signal_simple);
202 (void)signal(SIGFPE, handle_signal_abort);
206 (void)signal(SIGILL, handle_signal_abort);
210 (void)signal(SIGTRAP, handle_signal_abort);
214 (void)signal(SIGIOT, handle_signal_abort);
218 (void)signal(SIGKILL, handle_signal_abort);
222 (void)signal(SIGBUS, handle_signal_abort);
226 (void)signal(SIGSEGV, handle_signal_abort);
230 (void)signal(SIGTERM, handle_signal_abort);
234 (void)signal(SIGPIPE, handle_signal_abort);
238 (void)signal(SIGEMT, handle_signal_abort);
242 (void)signal(SIGDANGER, handle_signal_abort);
246 (void)signal(SIGSYS, handle_signal_abort);
250 (void)signal(SIGXCPU, handle_signal_abort);
254 (void)signal(SIGPWR, handle_signal_abort);