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_api.h" 10 #include "fuse_lowlevel.h" 11 12 #include <stdio.h> 13 #include <string.h> 14 #include <signal.h> 15 16 static struct fuse_session *fuse_instance; 17 18 static void exit_handler(int sig) 19 { 20 (void) sig; 21 if (fuse_instance) 22 fuse_session_exit(fuse_instance); 23 } 24 25 static int set_one_signal_handler(int sig, void (*handler)(int), int remove) 26 { 27 struct sigaction sa; 28 struct sigaction old_sa; 29 30 memset(&sa, 0, sizeof(struct sigaction)); 31 sa.sa_handler = remove ? SIG_DFL : handler; 32 sigemptyset(&(sa.sa_mask)); 33 sa.sa_flags = 0; 34 35 if (sigaction(sig, NULL, &old_sa) == -1) { 36 perror("fuse: cannot get old signal handler"); 37 return -1; 38 } 39 40 if (old_sa.sa_handler == (remove ? handler : SIG_DFL) && 41 sigaction(sig, &sa, NULL) == -1) { 42 perror("fuse: cannot set signal handler"); 43 return -1; 44 } 45 return 0; 46 } 47 48 int fuse_set_signal_handlers(struct fuse_session *se) 49 { 50 if (set_one_signal_handler(SIGHUP, exit_handler, 0) == -1 || 51 set_one_signal_handler(SIGINT, exit_handler, 0) == -1 || 52 set_one_signal_handler(SIGTERM, exit_handler, 0) == -1 || 53 set_one_signal_handler(SIGPIPE, SIG_IGN, 0) == -1) 54 return -1; 55 56 fuse_instance = se; 57 return 0; 58 } 59 60 void fuse_remove_signal_handlers(struct fuse_session *se) 61 { 62 if (fuse_instance != se) 63 fprintf(stderr, 64 "fuse: fuse_remove_signal_handlers: unknown session\n"); 65 else 66 fuse_instance = NULL; 67 68 set_one_signal_handler(SIGHUP, exit_handler, 1); 69 set_one_signal_handler(SIGINT, exit_handler, 1); 70 set_one_signal_handler(SIGTERM, exit_handler, 1); 71 set_one_signal_handler(SIGPIPE, SIG_IGN, 1); 72 } 73 74