11#include "fuse_config.h"
12#include "fuse_lowlevel.h"
29static int teardown_sigs[] = { SIGHUP, SIGINT, SIGTERM };
31static int ignore_sigs[] = { SIGPIPE};
32static int fail_sigs[] = { SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGSEGV };
33static struct fuse_session *fuse_instance;
36#define BT_STACK_SZ (1024 * 1024)
37static void *backtrace_buffer[BT_STACK_SZ];
40static void dump_stack(
void)
45 int nptrs = backtrace(backtrace_buffer, BT_STACK_SZ);
46 strings = backtrace_symbols(backtrace_buffer, nptrs);
48 if (strings == NULL) {
49 fuse_log(FUSE_LOG_ERR,
"Failed to get backtrace symbols: %s\n",
54 for (
int idx = 0; idx < nptrs; idx++)
55 fuse_log(FUSE_LOG_ERR,
"%s\n", strings[idx]);
61static void exit_handler(
int sig)
63 if (fuse_instance == NULL) {
64 fuse_log(FUSE_LOG_ERR,
"fuse_instance is NULL\n");
68 if (fuse_instance->debug)
69 fuse_log(FUSE_LOG_ERR,
"exit_handler called with sig %d\n",
76 "assertion error: signal value <= 0\n");
79 fuse_instance->error = sig;
82 fuse_instance->error = sig;
85static void exit_backtrace(
int sig)
87 if (fuse_instance == NULL)
93 fuse_log(FUSE_LOG_ERR,
"Got signal: %d\n", sig);
99static void do_nothing(
int sig)
104static int set_one_signal_handler(
int sig,
void (*handler)(
int),
int remove)
107 struct sigaction old_sa;
109 memset(&sa, 0,
sizeof(
struct sigaction));
110 sa.sa_handler = remove ? SIG_DFL : handler;
111 sigemptyset(&(sa.sa_mask));
114 if (sigaction(sig, NULL, &old_sa) == -1) {
115 perror(
"fuse: cannot get old signal handler");
119 if (old_sa.sa_handler == (remove ? handler : SIG_DFL) &&
120 sigaction(sig, &sa, NULL) == -1) {
121 perror(
"fuse: cannot set signal handler");
127static int _fuse_set_signal_handlers(
int signals[],
int nr_signals,
128 void (*handler)(
int))
130 for (
int idx = 0; idx < nr_signals; idx++) {
131 int signal = signals[idx];
140 if (set_one_signal_handler(signal, handler, 0) == -1) {
142 "Failed to install signal handler for sig %d\n",
156 nr_signals =
sizeof(teardown_sigs) /
sizeof(teardown_sigs[0]);
157 rc = _fuse_set_signal_handlers(teardown_sigs, nr_signals, exit_handler);
161 nr_signals =
sizeof(ignore_sigs) /
sizeof(ignore_sigs[0]);
162 rc = _fuse_set_signal_handlers(ignore_sigs, nr_signals, do_nothing);
178 size_t nr_signals =
sizeof(fail_sigs) /
sizeof(fail_sigs[0]);
180 int rc = _fuse_set_signal_handlers(fail_sigs, nr_signals,
191static void _fuse_remove_signal_handlers(
int signals[],
int nr_signals,
192 void (*handler)(
int))
194 for (
int idx = 0; idx < nr_signals; idx++)
195 set_one_signal_handler(signals[idx], handler, 1);
202 if (fuse_instance != se)
204 "fuse: fuse_remove_signal_handlers: unknown session\n");
206 fuse_instance = NULL;
208 nr_signals =
sizeof(teardown_sigs) /
sizeof(teardown_sigs[0]);
209 _fuse_remove_signal_handlers(teardown_sigs, nr_signals, exit_handler);
211 nr_signals =
sizeof(ignore_sigs) /
sizeof(ignore_sigs[0]);
212 _fuse_remove_signal_handlers(ignore_sigs, nr_signals, do_nothing);
214 nr_signals =
sizeof(fail_sigs) /
sizeof(fail_sigs[0]);
215 _fuse_remove_signal_handlers(fail_sigs, nr_signals, exit_backtrace);
int fuse_set_fail_signal_handlers(struct fuse_session *se)
int fuse_set_signal_handlers(struct fuse_session *se)
void fuse_remove_signal_handlers(struct fuse_session *se)
void fuse_log(enum fuse_log_level level, const char *fmt,...)
void fuse_session_exit(struct fuse_session *se)