11#include "fuse_config.h"
25static int teardown_sigs[] = { SIGHUP, SIGINT, SIGTERM };
26static int ignore_sigs[] = { SIGPIPE};
27static int fail_sigs[] = { SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGSEGV };
28static struct fuse_session *fuse_instance;
30#define BT_STACK_SZ (1024 * 1024)
31static void *backtrace_buffer[BT_STACK_SZ];
33static void dump_stack(
void)
38 int nptrs = backtrace(backtrace_buffer, BT_STACK_SZ);
39 strings = backtrace_symbols(backtrace_buffer, nptrs);
41 if (strings == NULL) {
42 fuse_log(FUSE_LOG_ERR,
"Failed to get backtrace symbols: %s\n",
47 for (
int idx = 0; idx < nptrs; idx++)
48 fuse_log(FUSE_LOG_ERR,
"%s\n", strings[idx]);
54static void exit_handler(
int sig)
56 if (fuse_instance == NULL)
63 "assertion error: signal value <= 0\n");
66 fuse_instance->error = sig;
69 fuse_instance->error = sig;
72static void exit_backtrace(
int sig)
74 if (fuse_instance == NULL)
80 fuse_log(FUSE_LOG_ERR,
"Got signal: %d\n", sig);
86static void do_nothing(
int sig)
91static int set_one_signal_handler(
int sig,
void (*handler)(
int),
int remove)
94 struct sigaction old_sa;
96 memset(&sa, 0,
sizeof(
struct sigaction));
97 sa.sa_handler = remove ? SIG_DFL : handler;
98 sigemptyset(&(sa.sa_mask));
101 if (sigaction(sig, NULL, &old_sa) == -1) {
102 perror(
"fuse: cannot get old signal handler");
106 if (old_sa.sa_handler == (remove ? handler : SIG_DFL) &&
107 sigaction(sig, &sa, NULL) == -1) {
108 perror(
"fuse: cannot set signal handler");
114static int _fuse_set_signal_handlers(
int signals[],
int nr_signals,
115 void (*handler)(
int))
117 for (
int idx = 0; idx < nr_signals; idx++) {
118 int signal = signals[idx];
127 if (set_one_signal_handler(signal, handler, 0) == -1) {
129 "Failed to install signal handler for sig %d\n",
143 nr_signals =
sizeof(teardown_sigs) /
sizeof(teardown_sigs[0]);
144 rc = _fuse_set_signal_handlers(teardown_sigs, nr_signals, exit_handler);
148 nr_signals =
sizeof(ignore_sigs) /
sizeof(ignore_sigs[0]);
149 rc = _fuse_set_signal_handlers(ignore_sigs, nr_signals, do_nothing);
165 size_t nr_signals =
sizeof(fail_sigs) /
sizeof(fail_sigs[0]);
167 int rc = _fuse_set_signal_handlers(fail_sigs, nr_signals,
178static void _fuse_remove_signal_handlers(
int signals[],
int nr_signals,
179 void (*handler)(
int))
181 for (
int idx = 0; idx < nr_signals; idx++)
182 set_one_signal_handler(signals[idx], handler, 1);
189 if (fuse_instance != se)
191 "fuse: fuse_remove_signal_handlers: unknown session\n");
193 fuse_instance = NULL;
195 nr_signals =
sizeof(teardown_sigs) /
sizeof(teardown_sigs[0]);
196 _fuse_remove_signal_handlers(teardown_sigs, nr_signals, exit_handler);
198 nr_signals =
sizeof(ignore_sigs) /
sizeof(ignore_sigs[0]);
199 _fuse_remove_signal_handlers(ignore_sigs, nr_signals, do_nothing);
201 nr_signals =
sizeof(fail_sigs) /
sizeof(fail_sigs[0]);
202 _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)