2 * @file signal-handlers.c
3 * @brief シグナルハンドラの管理 / Controlling signal handlers
8 #include "io/signal-handlers.h"
10 #include "core/game-closer.h"
14 #include "io/write-diary.h"
15 #include "cmd/cmd-dump.h"
16 #include "floor-events.h"
18 s16b signal_count; /* Hack -- Count interupts */
25 * @brief OSからのシグナルを受けてサスペンド状態に入る /
26 * Handle signals -- suspend
27 * @param sig 受け取ったシグナル
29 * Actually suspend the game, and then resume cleanly
31 static void handle_signal_suspend(int sig)
33 (void)signal(sig, SIG_IGN);
36 Term_xtra(TERM_XTRA_ALIVE, 0);
37 (void)kill(0, SIGSTOP);
38 Term_xtra(TERM_XTRA_ALIVE, 1);
42 (void)signal(sig, handle_signal_suspend);
47 * todo ここにplayer_typeを追加すると関数ポインタ周りの収拾がつかなくなるので保留
48 * @brief OSからのシグナルを受けて中断、終了する /
49 * Handle signals -- simple (interrupt and quit)
50 * @param sig 受け取ったシグナル
53 * This function was causing a *huge* number of problems, so it has
54 * been simplified greatly. We keep a global variable which counts
55 * the number of times the user attempts to kill the process, and
56 * we commit suicide if the user does this a certain number of times.
57 * We attempt to give "feedback" to the user as he approaches the
58 * suicide thresh-hold, but without penalizing accidental keypresses.
59 * To prevent messy accidents, we should reset this global variable
60 * whenever the user enters a keypress, or something like that.
63 static void handle_signal_simple(int sig)
65 (void)signal(sig, SIG_IGN);
66 if (!current_world_ptr->character_generated || current_world_ptr->character_saved)
72 (void)strcpy(p_ptr->died_from, _("強制終了", "Abortion"));
73 forget_lite(p_ptr->current_floor_ptr);
74 forget_view(p_ptr->current_floor_ptr);
75 clear_mon_lite(p_ptr->current_floor_ptr);
77 quit(_("強制終了", "interrupt"));
79 else if (signal_count >= 5)
81 (void)strcpy(p_ptr->died_from, _("強制終了中", "Interrupting"));
82 forget_lite(p_ptr->current_floor_ptr);
83 forget_view(p_ptr->current_floor_ptr);
84 clear_mon_lite(p_ptr->current_floor_ptr);
85 p_ptr->playing = FALSE;
86 p_ptr->is_dead = TRUE;
87 p_ptr->leaving = TRUE;
89 quit(_("強制終了", "interrupt"));
91 else if (signal_count >= 4)
93 Term_xtra(TERM_XTRA_NOISE, 0);
94 Term_erase(0, 0, 255);
95 Term_putstr(0, 0, -1, TERM_WHITE, _("熟慮の上の自殺!", "Contemplating suicide!"));
98 else if (signal_count >= 2)
100 Term_xtra(TERM_XTRA_NOISE, 0);
103 (void)signal(sig, handle_signal_simple);
108 * todo ここにp_ptrを追加すると関数ポインタ周りの収拾がつかなくなるので保留
109 * @brief OSからのシグナルを受けて強制終了する /
110 * Handle signal -- abort, kill, etc
111 * @param sig 受け取ったシグナル
115 * This function was causing a *huge* number of problems, so it has
116 * been simplified greatly. We keep a global variable which counts
117 * the number of times the user attempts to kill the process, and
118 * we commit suicide if the user does this a certain number of times.
119 * We attempt to give "feedback" to the user as he approaches the
120 * suicide thresh-hold, but without penalizing accidental keypresses.
121 * To prevent messy accidents, we should reset this global variable
122 * whenever the user enters a keypress, or something like that.
125 static void handle_signal_abort(int sig)
128 Term_get_size(&wid, &hgt);
130 (void)signal(sig, SIG_IGN);
131 if (!current_world_ptr->character_generated || current_world_ptr->character_saved) quit(NULL);
133 forget_lite(p_ptr->current_floor_ptr);
134 forget_view(p_ptr->current_floor_ptr);
135 clear_mon_lite(p_ptr->current_floor_ptr);
137 Term_erase(0, hgt - 1, 255);
138 Term_putstr(0, hgt - 1, -1, TERM_RED,
139 _("恐ろしいソフトのバグが飛びかかってきた!", "A gruesome software bug LEAPS out at you!"));
141 Term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ...", "Panic save..."));
143 exe_write_diary(p_ptr, DIARY_GAMESTART, 0, _("----ゲーム異常終了----", "-- Tried Panic Save and Aborted Game --"));
146 p_ptr->panic_save = 1;
147 (void)strcpy(p_ptr->died_from, _("(緊急セーブ)", "(panic save)"));
149 signals_ignore_tstp();
151 if (save_player(p_ptr))
153 Term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ成功!", "Panic save succeeded!"));
157 Term_putstr(45, hgt - 1, -1, TERM_RED, _("緊急セーブ失敗!", "Panic save failed!"));
161 quit(_("ソフトのバグ", "software bug"));
166 * @brief OSからのSIGTSTPシグナルを無視する関数 /
167 * Ignore SIGTSTP signals (keyboard suspend)
171 void signals_ignore_tstp(void)
174 (void)signal(SIGTSTP, SIG_IGN);
180 * @brief OSからのSIGTSTPシグナルハンドラ /
181 * Handle SIGTSTP signals (keyboard suspend)
185 void signals_handle_tstp(void)
188 (void)signal(SIGTSTP, handle_signal_suspend);
194 * @brief OSからのシグナルハンドルを初期化する /
195 * Prepare to handle the relevant signals
199 void signals_init(void)
202 (void)signal(SIGHUP, SIG_IGN);
206 (void)signal(SIGTSTP, handle_signal_suspend);
210 (void)signal(SIGINT, handle_signal_simple);
214 (void)signal(SIGQUIT, handle_signal_simple);
218 (void)signal(SIGFPE, handle_signal_abort);
222 (void)signal(SIGILL, handle_signal_abort);
226 (void)signal(SIGTRAP, handle_signal_abort);
230 (void)signal(SIGIOT, handle_signal_abort);
234 (void)signal(SIGKILL, handle_signal_abort);
238 (void)signal(SIGBUS, handle_signal_abort);
242 (void)signal(SIGSEGV, handle_signal_abort);
246 (void)signal(SIGTERM, handle_signal_abort);
250 (void)signal(SIGPIPE, handle_signal_abort);
254 (void)signal(SIGEMT, handle_signal_abort);
258 (void)signal(SIGDANGER, handle_signal_abort);
262 (void)signal(SIGSYS, handle_signal_abort);
266 (void)signal(SIGXCPU, handle_signal_abort);
270 (void)signal(SIGPWR, handle_signal_abort);
280 void signals_ignore_tstp(void)
289 void signals_handle_tstp(void)
298 void signals_init(void)