2313
|
1 /*
|
|
2 * Audacious
|
|
3 * Copyright (c) 2005-2007 Audacious development team
|
|
4 *
|
|
5 * BMP - Cross-platform multimedia player
|
|
6 * Copyright (C) 2003-2005 BMP development team.
|
|
7 *
|
|
8 * This program is free software; you can redistribute it and/or modify
|
|
9 * it under the terms of the GNU General Public License as published by
|
|
10 * the Free Software Foundation; under version 2 of the License.
|
|
11 *
|
|
12 * This program is distributed in the hope that it will be useful,
|
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 * GNU General Public License for more details.
|
|
16 *
|
|
17 * You should have received a copy of the GNU General Public License
|
|
18 * along with this program; if not, write to the Free Software
|
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
20 * 02110-1301, USA.
|
|
21 */
|
|
22
|
|
23 #include <glib.h>
|
|
24 #include <glib/gi18n.h>
|
|
25 #include <glib/gprintf.h>
|
|
26 #include <config.h>
|
|
27 #include <stdlib.h>
|
|
28 #include <unistd.h>
|
|
29 #include <sys/types.h>
|
|
30 #include <signal.h>
|
|
31
|
|
32 #include "main.h"
|
|
33 #include "ui_main.h"
|
|
34 #include "signals.h"
|
|
35
|
|
36 typedef void (*SignalHandler) (gint);
|
|
37
|
|
38 static SignalHandler
|
|
39 signal_install_handler_full (gint signal_number,
|
|
40 SignalHandler handler,
|
|
41 gint *signals_to_block,
|
|
42 gsize n_signals)
|
|
43 {
|
|
44 struct sigaction action, old_action;
|
|
45 gsize i;
|
|
46
|
|
47 action.sa_handler = handler;
|
|
48 action.sa_flags = SA_RESTART;
|
|
49
|
|
50 sigemptyset (&action.sa_mask);
|
|
51
|
|
52 for (i = 0; i < n_signals; i++)
|
|
53 sigaddset (&action.sa_mask, signals_to_block[i]);
|
|
54
|
|
55 if (sigaction (signal_number, &action, &old_action) == -1)
|
|
56 {
|
|
57 g_message ("Failed to install handler for signal %d", signal_number);
|
|
58 return NULL;
|
|
59 }
|
|
60
|
|
61 return old_action.sa_handler;
|
|
62 }
|
|
63
|
|
64 /*
|
|
65 * A version of signal() that works more reliably across different
|
|
66 * platforms. It:
|
|
67 * a. restarts interrupted system calls
|
|
68 * b. does not reset the handler
|
|
69 * c. blocks the same signal within the handler
|
|
70 *
|
|
71 * (adapted from Unix Network Programming Vol. 1)
|
|
72 */
|
|
73 static SignalHandler
|
|
74 signal_install_handler (gint signal_number,
|
|
75 SignalHandler handler)
|
|
76 {
|
|
77 return signal_install_handler_full (signal_number, handler, NULL, 0);
|
|
78 }
|
|
79
|
|
80 static void
|
|
81 signal_empty_handler (gint signal_number)
|
|
82 {
|
|
83 /* empty */
|
|
84 }
|
|
85
|
|
86 static void
|
|
87 sigsegv_handler (gint signal_number)
|
|
88 {
|
|
89 #ifndef SIGSEGV_ABORT
|
|
90 g_printerr(_("\nReceived SIGSEGV\n\n"
|
|
91 "This could be a bug in Audacious. If you don't know why this happened, "
|
|
92 "file a bug at http://bugs-meta.atheme.org/\n\n"));
|
|
93 g_critical("Received SIGSEGV");
|
|
94
|
|
95 /* TO DO: log stack trace and possibly dump config file. */
|
|
96 exit (EXIT_FAILURE);
|
|
97 #else
|
|
98 abort ();
|
|
99 #endif
|
|
100 }
|
|
101
|
|
102 static void
|
|
103 sigterm_handler (gint signal_number)
|
|
104 {
|
|
105 cfg.terminate = TRUE;
|
|
106 }
|
|
107
|
|
108 static gboolean
|
|
109 signal_process_events (gpointer data)
|
|
110 {
|
|
111 if (cfg.terminate == TRUE)
|
|
112 {
|
|
113 g_message("Audacious has received SIGTERM and is shutting down.");
|
|
114 mainwin_quit_cb();
|
|
115 return FALSE;
|
|
116 }
|
|
117
|
|
118 return TRUE;
|
|
119 }
|
|
120
|
|
121 void
|
|
122 signal_handlers_init (void)
|
|
123 {
|
|
124 char *magic;
|
|
125 magic = getenv("AUD_ENSURE_BACKTRACE");
|
|
126
|
|
127 signal_install_handler(SIGPIPE, signal_empty_handler);
|
|
128 signal_install_handler(SIGINT, sigterm_handler);
|
|
129 signal_install_handler(SIGTERM, sigterm_handler);
|
|
130
|
|
131 /* in particular environment (maybe with glibc 2.5), core file
|
|
132 through signal handler doesn't contain useful back trace. --yaz */
|
|
133 if (magic == NULL)
|
|
134 signal_install_handler(SIGSEGV, sigsegv_handler);
|
|
135
|
|
136 g_timeout_add(100, signal_process_events, NULL);
|
|
137 }
|