1987da915Sopenharmony_ci/* 2987da915Sopenharmony_ci FUSE: Filesystem in Userspace 3987da915Sopenharmony_ci Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> 4987da915Sopenharmony_ci 5987da915Sopenharmony_ci This program can be distributed under the terms of the GNU LGPLv2. 6987da915Sopenharmony_ci See the file COPYING.LIB 7987da915Sopenharmony_ci*/ 8987da915Sopenharmony_ci 9987da915Sopenharmony_ci#include "config.h" 10987da915Sopenharmony_ci#include "fuse_lowlevel.h" 11987da915Sopenharmony_ci 12987da915Sopenharmony_ci#include <stdio.h> 13987da915Sopenharmony_ci#include <string.h> 14987da915Sopenharmony_ci#include <signal.h> 15987da915Sopenharmony_ci 16987da915Sopenharmony_cistatic struct fuse_session *fuse_instance; 17987da915Sopenharmony_ci 18987da915Sopenharmony_cistatic void exit_handler(int sig) 19987da915Sopenharmony_ci{ 20987da915Sopenharmony_ci (void) sig; 21987da915Sopenharmony_ci if (fuse_instance) 22987da915Sopenharmony_ci fuse_session_exit(fuse_instance); 23987da915Sopenharmony_ci} 24987da915Sopenharmony_ci 25987da915Sopenharmony_cistatic int set_one_signal_handler(int sig, void (*handler)(int), int remove) 26987da915Sopenharmony_ci{ 27987da915Sopenharmony_ci struct sigaction sa; 28987da915Sopenharmony_ci struct sigaction old_sa; 29987da915Sopenharmony_ci 30987da915Sopenharmony_ci memset(&sa, 0, sizeof(struct sigaction)); 31987da915Sopenharmony_ci sa.sa_handler = remove ? SIG_DFL : handler; 32987da915Sopenharmony_ci sigemptyset(&(sa.sa_mask)); 33987da915Sopenharmony_ci sa.sa_flags = 0; 34987da915Sopenharmony_ci 35987da915Sopenharmony_ci if (sigaction(sig, NULL, &old_sa) == -1) { 36987da915Sopenharmony_ci perror("fuse: cannot get old signal handler"); 37987da915Sopenharmony_ci return -1; 38987da915Sopenharmony_ci } 39987da915Sopenharmony_ci 40987da915Sopenharmony_ci if (old_sa.sa_handler == (remove ? handler : SIG_DFL) && 41987da915Sopenharmony_ci sigaction(sig, &sa, NULL) == -1) { 42987da915Sopenharmony_ci perror("fuse: cannot set signal handler"); 43987da915Sopenharmony_ci return -1; 44987da915Sopenharmony_ci } 45987da915Sopenharmony_ci return 0; 46987da915Sopenharmony_ci} 47987da915Sopenharmony_ci 48987da915Sopenharmony_ciint fuse_set_signal_handlers(struct fuse_session *se) 49987da915Sopenharmony_ci{ 50987da915Sopenharmony_ci if (set_one_signal_handler(SIGHUP, exit_handler, 0) == -1 || 51987da915Sopenharmony_ci set_one_signal_handler(SIGINT, exit_handler, 0) == -1 || 52987da915Sopenharmony_ci set_one_signal_handler(SIGTERM, exit_handler, 0) == -1 || 53987da915Sopenharmony_ci set_one_signal_handler(SIGPIPE, SIG_IGN, 0) == -1) 54987da915Sopenharmony_ci return -1; 55987da915Sopenharmony_ci 56987da915Sopenharmony_ci fuse_instance = se; 57987da915Sopenharmony_ci return 0; 58987da915Sopenharmony_ci} 59987da915Sopenharmony_ci 60987da915Sopenharmony_civoid fuse_remove_signal_handlers(struct fuse_session *se) 61987da915Sopenharmony_ci{ 62987da915Sopenharmony_ci if (fuse_instance != se) 63987da915Sopenharmony_ci fprintf(stderr, 64987da915Sopenharmony_ci "fuse: fuse_remove_signal_handlers: unknown session\n"); 65987da915Sopenharmony_ci else 66987da915Sopenharmony_ci fuse_instance = NULL; 67987da915Sopenharmony_ci 68987da915Sopenharmony_ci set_one_signal_handler(SIGHUP, exit_handler, 1); 69987da915Sopenharmony_ci set_one_signal_handler(SIGINT, exit_handler, 1); 70987da915Sopenharmony_ci set_one_signal_handler(SIGTERM, exit_handler, 1); 71987da915Sopenharmony_ci set_one_signal_handler(SIGPIPE, SIG_IGN, 1); 72987da915Sopenharmony_ci} 73987da915Sopenharmony_ci 74