linux/tools/lib/subcmd/sigchain.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <signal.h>
   3#include "subcmd-util.h"
   4#include "sigchain.h"
   5
   6#define SIGCHAIN_MAX_SIGNALS 32
   7
   8struct sigchain_signal {
   9        sigchain_fun *old;
  10        int n;
  11        int alloc;
  12};
  13static struct sigchain_signal signals[SIGCHAIN_MAX_SIGNALS];
  14
  15static void check_signum(int sig)
  16{
  17        if (sig < 1 || sig >= SIGCHAIN_MAX_SIGNALS)
  18                die("BUG: signal out of range: %d", sig);
  19}
  20
  21static int sigchain_push(int sig, sigchain_fun f)
  22{
  23        struct sigchain_signal *s = signals + sig;
  24        check_signum(sig);
  25
  26        ALLOC_GROW(s->old, s->n + 1, s->alloc);
  27        s->old[s->n] = signal(sig, f);
  28        if (s->old[s->n] == SIG_ERR)
  29                return -1;
  30        s->n++;
  31        return 0;
  32}
  33
  34int sigchain_pop(int sig)
  35{
  36        struct sigchain_signal *s = signals + sig;
  37        check_signum(sig);
  38        if (s->n < 1)
  39                return 0;
  40
  41        if (signal(sig, s->old[s->n - 1]) == SIG_ERR)
  42                return -1;
  43        s->n--;
  44        return 0;
  45}
  46
  47void sigchain_push_common(sigchain_fun f)
  48{
  49        sigchain_push(SIGINT, f);
  50        sigchain_push(SIGHUP, f);
  51        sigchain_push(SIGTERM, f);
  52        sigchain_push(SIGQUIT, f);
  53        sigchain_push(SIGPIPE, f);
  54}
  55