busybox/libbb/signals.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Utility routines.
   4 *
   5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
   6 * Copyright (C) 2006 Rob Landley
   7 * Copyright (C) 2006 Denys Vlasenko
   8 *
   9 * Licensed under GPLv2, see file LICENSE in this source tree.
  10 */
  11#include "libbb.h"
  12
  13/* All known arches use small ints for signals */
  14smallint bb_got_signal;
  15
  16void record_signo(int signo)
  17{
  18        bb_got_signal = signo;
  19}
  20
  21/* Saves 2 bytes on x86! Oh my... */
  22int FAST_FUNC sigaction_set(int signum, const struct sigaction *act)
  23{
  24        return sigaction(signum, act, NULL);
  25}
  26
  27int FAST_FUNC sigprocmask_allsigs(int how)
  28{
  29        sigset_t set;
  30        sigfillset(&set);
  31        return sigprocmask(how, &set, NULL);
  32}
  33
  34int FAST_FUNC sigprocmask2(int how, sigset_t *set)
  35{
  36        // Grr... gcc 8.1.1:
  37        // "passing argument 3 to restrict-qualified parameter aliases with argument 2"
  38        // dance around that...
  39        sigset_t *oset FIX_ALIASING;
  40        oset = set;
  41        return sigprocmask(how, set, oset);
  42}
  43
  44void FAST_FUNC bb_signals(int sigs, void (*f)(int))
  45{
  46        int sig_no = 0;
  47        int bit = 1;
  48
  49        while (sigs) {
  50                if (sigs & bit) {
  51                        sigs -= bit;
  52                        signal(sig_no, f);
  53                }
  54                sig_no++;
  55                bit <<= 1;
  56        }
  57}
  58
  59void FAST_FUNC bb_signals_norestart(int sigs, void (*f)(int))
  60{
  61        int sig_no = 0;
  62        int bit = 1;
  63        struct sigaction sa;
  64
  65        memset(&sa, 0, sizeof(sa));
  66        sa.sa_handler = f;
  67        /*sa.sa_flags = 0;*/
  68        /*sigemptyset(&sa.sa_mask); - hope memset did it*/
  69
  70        while (sigs) {
  71                if (sigs & bit) {
  72                        sigs -= bit;
  73                        sigaction_set(sig_no, &sa);
  74                }
  75                sig_no++;
  76                bit <<= 1;
  77        }
  78}
  79
  80void FAST_FUNC sig_block(int sig)
  81{
  82        sigset_t ss;
  83        sigemptyset(&ss);
  84        sigaddset(&ss, sig);
  85        sigprocmask(SIG_BLOCK, &ss, NULL);
  86}
  87
  88void FAST_FUNC sig_unblock(int sig)
  89{
  90        sigset_t ss;
  91        sigemptyset(&ss);
  92        sigaddset(&ss, sig);
  93        sigprocmask(SIG_UNBLOCK, &ss, NULL);
  94}
  95
  96void FAST_FUNC wait_for_any_sig(void)
  97{
  98        sigset_t ss;
  99        sigemptyset(&ss);
 100        sigsuspend(&ss);
 101}
 102
 103/* Assuming the sig is fatal */
 104void FAST_FUNC kill_myself_with_sig(int sig)
 105{
 106        signal(sig, SIG_DFL);
 107        sig_unblock(sig);
 108        raise(sig);
 109        _exit(sig | 128); /* Should not reach it */
 110}
 111
 112void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int))
 113{
 114        struct sigaction sa;
 115        memset(&sa, 0, sizeof(sa));
 116        /*sigemptyset(&sa.sa_mask);*/
 117        sa.sa_flags = SA_RESTART;
 118        sa.sa_handler = handler;
 119        sigaction_set(sig, &sa);
 120}
 121
 122void FAST_FUNC signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int))
 123{
 124        struct sigaction sa;
 125        memset(&sa, 0, sizeof(sa));
 126        /*sigemptyset(&sa.sa_mask);*/
 127        /*sa.sa_flags = 0;*/
 128        sa.sa_handler = handler;
 129        sigaction_set(sig, &sa);
 130}
 131