16881f68fSopenharmony_ci/* 26881f68fSopenharmony_ci FUSE: Filesystem in Userspace 36881f68fSopenharmony_ci Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> 46881f68fSopenharmony_ci 56881f68fSopenharmony_ci Utility functions for setting signal handlers. 66881f68fSopenharmony_ci 76881f68fSopenharmony_ci This program can be distributed under the terms of the GNU LGPLv2. 86881f68fSopenharmony_ci See the file COPYING.LIB 96881f68fSopenharmony_ci*/ 106881f68fSopenharmony_ci 116881f68fSopenharmony_ci#include "fuse_config.h" 126881f68fSopenharmony_ci#include "fuse_lowlevel.h" 136881f68fSopenharmony_ci#include "fuse_i.h" 146881f68fSopenharmony_ci 156881f68fSopenharmony_ci#include <stdio.h> 166881f68fSopenharmony_ci#include <string.h> 176881f68fSopenharmony_ci#include <signal.h> 186881f68fSopenharmony_ci#include <stdlib.h> 196881f68fSopenharmony_ci 206881f68fSopenharmony_cistatic struct fuse_session *fuse_instance; 216881f68fSopenharmony_ci 226881f68fSopenharmony_cistatic void exit_handler(int sig) 236881f68fSopenharmony_ci{ 246881f68fSopenharmony_ci if (fuse_instance) { 256881f68fSopenharmony_ci fuse_session_exit(fuse_instance); 266881f68fSopenharmony_ci if(sig <= 0) { 276881f68fSopenharmony_ci fuse_log(FUSE_LOG_ERR, "assertion error: signal value <= 0\n"); 286881f68fSopenharmony_ci abort(); 296881f68fSopenharmony_ci } 306881f68fSopenharmony_ci fuse_instance->error = sig; 316881f68fSopenharmony_ci } 326881f68fSopenharmony_ci} 336881f68fSopenharmony_ci 346881f68fSopenharmony_cistatic void do_nothing(int sig) 356881f68fSopenharmony_ci{ 366881f68fSopenharmony_ci (void) sig; 376881f68fSopenharmony_ci} 386881f68fSopenharmony_ci 396881f68fSopenharmony_cistatic int set_one_signal_handler(int sig, void (*handler)(int), int remove) 406881f68fSopenharmony_ci{ 416881f68fSopenharmony_ci struct sigaction sa; 426881f68fSopenharmony_ci struct sigaction old_sa; 436881f68fSopenharmony_ci 446881f68fSopenharmony_ci memset(&sa, 0, sizeof(struct sigaction)); 456881f68fSopenharmony_ci sa.sa_handler = remove ? SIG_DFL : handler; 466881f68fSopenharmony_ci sigemptyset(&(sa.sa_mask)); 476881f68fSopenharmony_ci sa.sa_flags = 0; 486881f68fSopenharmony_ci 496881f68fSopenharmony_ci if (sigaction(sig, NULL, &old_sa) == -1) { 506881f68fSopenharmony_ci perror("fuse: cannot get old signal handler"); 516881f68fSopenharmony_ci return -1; 526881f68fSopenharmony_ci } 536881f68fSopenharmony_ci 546881f68fSopenharmony_ci if (old_sa.sa_handler == (remove ? handler : SIG_DFL) && 556881f68fSopenharmony_ci sigaction(sig, &sa, NULL) == -1) { 566881f68fSopenharmony_ci perror("fuse: cannot set signal handler"); 576881f68fSopenharmony_ci return -1; 586881f68fSopenharmony_ci } 596881f68fSopenharmony_ci return 0; 606881f68fSopenharmony_ci} 616881f68fSopenharmony_ci 626881f68fSopenharmony_ciint fuse_set_signal_handlers(struct fuse_session *se) 636881f68fSopenharmony_ci{ 646881f68fSopenharmony_ci /* If we used SIG_IGN instead of the do_nothing function, 656881f68fSopenharmony_ci then we would be unable to tell if we set SIG_IGN (and 666881f68fSopenharmony_ci thus should reset to SIG_DFL in fuse_remove_signal_handlers) 676881f68fSopenharmony_ci or if it was already set to SIG_IGN (and should be left 686881f68fSopenharmony_ci untouched. */ 696881f68fSopenharmony_ci if (set_one_signal_handler(SIGHUP, exit_handler, 0) == -1 || 706881f68fSopenharmony_ci set_one_signal_handler(SIGINT, exit_handler, 0) == -1 || 716881f68fSopenharmony_ci set_one_signal_handler(SIGTERM, exit_handler, 0) == -1 || 726881f68fSopenharmony_ci set_one_signal_handler(SIGPIPE, do_nothing, 0) == -1) 736881f68fSopenharmony_ci return -1; 746881f68fSopenharmony_ci 756881f68fSopenharmony_ci fuse_instance = se; 766881f68fSopenharmony_ci return 0; 776881f68fSopenharmony_ci} 786881f68fSopenharmony_ci 796881f68fSopenharmony_civoid fuse_remove_signal_handlers(struct fuse_session *se) 806881f68fSopenharmony_ci{ 816881f68fSopenharmony_ci if (fuse_instance != se) 826881f68fSopenharmony_ci fuse_log(FUSE_LOG_ERR, 836881f68fSopenharmony_ci "fuse: fuse_remove_signal_handlers: unknown session\n"); 846881f68fSopenharmony_ci else 856881f68fSopenharmony_ci fuse_instance = NULL; 866881f68fSopenharmony_ci 876881f68fSopenharmony_ci set_one_signal_handler(SIGHUP, exit_handler, 1); 886881f68fSopenharmony_ci set_one_signal_handler(SIGINT, exit_handler, 1); 896881f68fSopenharmony_ci set_one_signal_handler(SIGTERM, exit_handler, 1); 906881f68fSopenharmony_ci set_one_signal_handler(SIGPIPE, do_nothing, 1); 916881f68fSopenharmony_ci} 92