cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

fuse_signals.c (2556B)


      1/*
      2 * FUSE: Filesystem in Userspace
      3 * Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
      4 *
      5 * Utility functions for setting signal handlers.
      6 *
      7 * This program can be distributed under the terms of the GNU LGPLv2.
      8 * See the file COPYING.LIB
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "fuse_i.h"
     13#include "fuse_lowlevel.h"
     14
     15
     16static struct fuse_session *fuse_instance;
     17
     18static void exit_handler(int sig)
     19{
     20    if (fuse_instance) {
     21        fuse_session_exit(fuse_instance);
     22        if (sig <= 0) {
     23            fuse_log(FUSE_LOG_ERR, "assertion error: signal value <= 0\n");
     24            abort();
     25        }
     26        fuse_instance->error = sig;
     27    }
     28}
     29
     30static void do_nothing(int sig)
     31{
     32    (void)sig;
     33}
     34
     35static int set_one_signal_handler(int sig, void (*handler)(int), int remove)
     36{
     37    struct sigaction sa;
     38    struct sigaction old_sa;
     39
     40    memset(&sa, 0, sizeof(struct sigaction));
     41    sa.sa_handler = remove ? SIG_DFL : handler;
     42    sigemptyset(&(sa.sa_mask));
     43    sa.sa_flags = 0;
     44
     45    if (sigaction(sig, NULL, &old_sa) == -1) {
     46        fuse_log(FUSE_LOG_ERR, "fuse: cannot get old signal handler: %s\n",
     47                 strerror(errno));
     48        return -1;
     49    }
     50
     51    if (old_sa.sa_handler == (remove ? handler : SIG_DFL) &&
     52        sigaction(sig, &sa, NULL) == -1) {
     53        fuse_log(FUSE_LOG_ERR, "fuse: cannot set signal handler: %s\n",
     54                 strerror(errno));
     55        return -1;
     56    }
     57    return 0;
     58}
     59
     60int fuse_set_signal_handlers(struct fuse_session *se)
     61{
     62    /*
     63     * If we used SIG_IGN instead of the do_nothing function,
     64     * then we would be unable to tell if we set SIG_IGN (and
     65     * thus should reset to SIG_DFL in fuse_remove_signal_handlers)
     66     * or if it was already set to SIG_IGN (and should be left
     67     * untouched.
     68     */
     69    if (set_one_signal_handler(SIGHUP, exit_handler, 0) == -1 ||
     70        set_one_signal_handler(SIGINT, exit_handler, 0) == -1 ||
     71        set_one_signal_handler(SIGTERM, exit_handler, 0) == -1 ||
     72        set_one_signal_handler(SIGPIPE, do_nothing, 0) == -1) {
     73        return -1;
     74    }
     75
     76    fuse_instance = se;
     77    return 0;
     78}
     79
     80void fuse_remove_signal_handlers(struct fuse_session *se)
     81{
     82    if (fuse_instance != se) {
     83        fuse_log(FUSE_LOG_ERR,
     84                 "fuse: fuse_remove_signal_handlers: unknown session\n");
     85    } else {
     86        fuse_instance = NULL;
     87    }
     88
     89    set_one_signal_handler(SIGHUP, exit_handler, 1);
     90    set_one_signal_handler(SIGINT, exit_handler, 1);
     91    set_one_signal_handler(SIGTERM, exit_handler, 1);
     92    set_one_signal_handler(SIGPIPE, do_nothing, 1);
     93}