1 /*
2   FUSE: Filesystem in Userspace
3   Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
4 
5   This program can be distributed under the terms of the GNU LGPLv2.
6   See the file COPYING.LIB
7 */
8 
9 #include "fuse_lowlevel.h"
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <signal.h>
14 
15 static struct fuse_session *fuse_instance;
16 
17 static void exit_handler(int sig)
18 {
19 	(void) sig;
20 	if (fuse_instance)
21 		fuse_session_exit(fuse_instance);
22 }
23 
24 static int set_one_signal_handler(int sig, void (*handler)(int), int remove)
25 {
26 	struct sigaction sa;
27 	struct sigaction old_sa;
28 
29 	memset(&sa, 0, sizeof(struct sigaction));
30 	sa.sa_handler = remove ? SIG_DFL : handler;
31 	sigemptyset(&(sa.sa_mask));
32 	sa.sa_flags = 0;
33 
34 	if (sigaction(sig, NULL, &old_sa) == -1) {
35 		perror("fuse: cannot get old signal handler");
36 		return -1;
37 	}
38 
39 	if (old_sa.sa_handler == (remove ? handler : SIG_DFL) &&
40 	    sigaction(sig, &sa, NULL) == -1) {
41 		perror("fuse: cannot set signal handler");
42 		return -1;
43 	}
44 	return 0;
45 }
46 
47 int fuse_set_signal_handlers(struct fuse_session *se)
48 {
49 	if (set_one_signal_handler(SIGHUP, exit_handler, 0) == -1 ||
50 	    set_one_signal_handler(SIGINT, exit_handler, 0) == -1 ||
51 	    set_one_signal_handler(SIGTERM, exit_handler, 0) == -1 ||
52 	    set_one_signal_handler(SIGPIPE, SIG_IGN, 0) == -1)
53 		return -1;
54 
55 	fuse_instance = se;
56 	return 0;
57 }
58 
59 void fuse_remove_signal_handlers(struct fuse_session *se)
60 {
61 	if (fuse_instance != se)
62 		fprintf(stderr,
63 			"fuse: fuse_remove_signal_handlers: unknown session\n");
64 	else
65 		fuse_instance = NULL;
66 
67 	set_one_signal_handler(SIGHUP, exit_handler, 1);
68 	set_one_signal_handler(SIGINT, exit_handler, 1);
69 	set_one_signal_handler(SIGTERM, exit_handler, 1);
70 	set_one_signal_handler(SIGPIPE, SIG_IGN, 1);
71 }
72 
73