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
  34void FAST_FUNC bb_signals(int sigs, void (*f)(int))
  35{
  36        int sig_no = 0;
  37        int bit = 1;
  38
  39        while (sigs) {
  40                if (sigs & bit) {
  41                        sigs -= bit;
  42                        signal(sig_no, f);
  43                }
  44                sig_no++;
  45                bit <<= 1;
  46        }
  47}
  48
  49void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int))
  50{
  51        int sig_no = 0;
  52        int bit = 1;
  53        struct sigaction sa;
  54
  55        memset(&sa, 0, sizeof(sa));
  56        sa.sa_handler = f;
  57        /*sa.sa_flags = 0;*/
  58        /*sigemptyset(&sa.sa_mask); - hope memset did it*/
  59
  60        while (sigs) {
  61                if (sigs & bit) {
  62                        sigs -= bit;
  63                        sigaction_set(sig_no, &sa);
  64                }
  65                sig_no++;
  66                bit <<= 1;
  67        }
  68}
  69
  70void FAST_FUNC sig_block(int sig)
  71{
  72        sigset_t ss;
  73        sigemptyset(&ss);
  74        sigaddset(&ss, sig);
  75        sigprocmask(SIG_BLOCK, &ss, NULL);
  76}
  77
  78void FAST_FUNC sig_unblock(int sig)
  79{
  80        sigset_t ss;
  81        sigemptyset(&ss);
  82        sigaddset(&ss, sig);
  83        sigprocmask(SIG_UNBLOCK, &ss, NULL);
  84}
  85
  86void FAST_FUNC wait_for_any_sig(void)
  87{
  88        sigset_t ss;
  89        sigemptyset(&ss);
  90        sigsuspend(&ss);
  91}
  92
  93/* Assuming the sig is fatal */
  94void FAST_FUNC kill_myself_with_sig(int sig)
  95{
  96        signal(sig, SIG_DFL);
  97        sig_unblock(sig);
  98        raise(sig);
  99        _exit(sig | 128); /* Should not reach it */
 100}
 101
 102void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int))
 103{
 104        struct sigaction sa;
 105        memset(&sa, 0, sizeof(sa));
 106        /*sigemptyset(&sa.sa_mask);*/
 107        sa.sa_flags = SA_RESTART;
 108        sa.sa_handler = handler;
 109        sigaction_set(sig, &sa);
 110}
 111
 112void FAST_FUNC signal_no_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 = 0;*/
 118        sa.sa_handler = handler;
 119        sigaction_set(sig, &sa);
 120}
 121