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