11#include "fuse_config.h"
12#include "fuse_lowlevel.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;
31#define BT_STACK_SZ (1024 * 1024)
32static void *backtrace_buffer[BT_STACK_SZ];
35static void dump_stack(
void)
40 int nptrs = backtrace(backtrace_buffer, BT_STACK_SZ);
41 strings = backtrace_symbols(backtrace_buffer, nptrs);
43 if (strings == NULL) {
44 fuse_log(FUSE_LOG_ERR,
"Failed to get backtrace symbols: %s\n",
49 for (
int idx = 0; idx < nptrs; idx++)
50 fuse_log(FUSE_LOG_ERR,
"%s\n", strings[idx]);
56static void exit_handler(
int sig)
58 if (fuse_instance == NULL)
65 "assertion error: signal value <= 0\n");
68 fuse_instance->error = sig;
71 fuse_instance->error = sig;
74static void exit_backtrace(
int sig)
76 if (fuse_instance == NULL)
82 fuse_log(FUSE_LOG_ERR,
"Got signal: %d\n", sig);
88static void do_nothing(
int sig)
93static int set_one_signal_handler(
int sig,
void (*handler)(
int),
int remove)
96 struct sigaction old_sa;
98 memset(&sa, 0,
sizeof(
struct sigaction));
99 sa.sa_handler = remove ? SIG_DFL : handler;
100 sigemptyset(&(sa.sa_mask));
103 if (sigaction(sig, NULL, &old_sa) == -1) {
104 perror(
"fuse: cannot get old signal handler");
108 if (old_sa.sa_handler == (remove ? handler : SIG_DFL) &&
109 sigaction(sig, &sa, NULL) == -1) {
110 perror(
"fuse: cannot set signal handler");
116static int _fuse_set_signal_handlers(
int signals[],
int nr_signals,
117 void (*handler)(
int))
119 for (
int idx = 0; idx < nr_signals; idx++) {
120 int signal = signals[idx];
129 if (set_one_signal_handler(signal, handler, 0) == -1) {
131 "Failed to install signal handler for sig %d\n",
145 nr_signals =
sizeof(teardown_sigs) /
sizeof(teardown_sigs[0]);
146 rc = _fuse_set_signal_handlers(teardown_sigs, nr_signals, exit_handler);
150 nr_signals =
sizeof(ignore_sigs) /
sizeof(ignore_sigs[0]);
151 rc = _fuse_set_signal_handlers(ignore_sigs, nr_signals, do_nothing);
167 size_t nr_signals =
sizeof(fail_sigs) /
sizeof(fail_sigs[0]);
169 int rc = _fuse_set_signal_handlers(fail_sigs, nr_signals,
180static void _fuse_remove_signal_handlers(
int signals[],
int nr_signals,
181 void (*handler)(
int))
183 for (
int idx = 0; idx < nr_signals; idx++)
184 set_one_signal_handler(signals[idx], handler, 1);
191 if (fuse_instance != se)
193 "fuse: fuse_remove_signal_handlers: unknown session\n");
195 fuse_instance = NULL;
197 nr_signals =
sizeof(teardown_sigs) /
sizeof(teardown_sigs[0]);
198 _fuse_remove_signal_handlers(teardown_sigs, nr_signals, exit_handler);
200 nr_signals =
sizeof(ignore_sigs) /
sizeof(ignore_sigs[0]);
201 _fuse_remove_signal_handlers(ignore_sigs, nr_signals, do_nothing);
203 nr_signals =
sizeof(fail_sigs) /
sizeof(fail_sigs[0]);
204 _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)