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 GPL version 2, see file LICENSE in this tarball for details.
  10 */
  11
  12#include "libbb.h"
  13
  14/* All known arches use small ints for signals */
  15smallint bb_got_signal;
  16
  17void record_signo(int signo)
  18{
  19        bb_got_signal = signo;
  20}
  21
  22/* Saves 2 bytes on x86! Oh my... */
  23int FAST_FUNC sigaction_set(int signum, const struct sigaction *act)
  24{
  25        return sigaction(signum, act, NULL);
  26}
  27
  28int FAST_FUNC sigprocmask_allsigs(int how)
  29{
  30        sigset_t set;
  31        sigfillset(&set);
  32        return sigprocmask(how, &set, NULL);
  33}
  34
  35void FAST_FUNC bb_signals(int sigs, void (*f)(int))
  36{
  37        int sig_no = 0;
  38        int bit = 1;
  39
  40        while (sigs) {
  41                if (sigs & bit) {
  42                        sigs &= ~bit;
  43                        signal(sig_no, f);
  44                }
  45                sig_no++;
  46                bit <<= 1;
  47        }
  48}
  49
  50void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int))
  51{
  52        int sig_no = 0;
  53        int bit = 1;
  54        struct sigaction sa;
  55
  56        memset(&sa, 0, sizeof(sa));
  57        sa.sa_handler = f;
  58        /*sa.sa_flags = 0;*/
  59        /*sigemptyset(&sa.sa_mask); - hope memset did it*/
  60
  61        while (sigs) {
  62                if (sigs & bit) {
  63                        sigs &= ~bit;
  64                        sigaction_set(sig_no, &sa);
  65                }
  66                sig_no++;
  67                bit <<= 1;
  68        }
  69}
  70
  71void FAST_FUNC sig_block(int sig)
  72{
  73        sigset_t ss;
  74        sigemptyset(&ss);
  75        sigaddset(&ss, sig);
  76        sigprocmask(SIG_BLOCK, &ss, NULL);
  77}
  78
  79void FAST_FUNC sig_unblock(int sig)
  80{
  81        sigset_t ss;
  82        sigemptyset(&ss);
  83        sigaddset(&ss, sig);
  84        sigprocmask(SIG_UNBLOCK, &ss, NULL);
  85}
  86
  87void FAST_FUNC wait_for_any_sig(void)
  88{
  89        sigset_t ss;
  90        sigemptyset(&ss);
  91        sigsuspend(&ss);
  92}
  93
  94/* Assuming the sig is fatal */
  95void FAST_FUNC kill_myself_with_sig(int sig)
  96{
  97        signal(sig, SIG_DFL);
  98        sig_unblock(sig);
  99        raise(sig);
 100        _exit(EXIT_FAILURE); /* Should not reach it */
 101}
 102
 103void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int))
 104{
 105        struct sigaction sa;
 106        memset(&sa, 0, sizeof(sa));
 107        /*sigemptyset(&sa.sa_mask);*/
 108        sa.sa_flags = SA_RESTART;
 109        sa.sa_handler = handler;
 110        sigaction_set(sig, &sa);
 111}
 112
 113void FAST_FUNC signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int))
 114{
 115        struct sigaction sa;
 116        memset(&sa, 0, sizeof(sa));
 117        /*sigemptyset(&sa.sa_mask);*/
 118        /*sa.sa_flags = 0;*/
 119        sa.sa_handler = handler;
 120        sigaction_set(sig, &sa);
 121}
 122