2008-02-16 22:58:56 +00:00
|
|
|
/* vi: set sw=4 ts=4: */
|
|
|
|
/*
|
|
|
|
* Utility routines.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
|
|
|
|
* Copyright (C) 2006 Rob Landley
|
2008-03-02 12:53:15 +00:00
|
|
|
* Copyright (C) 2006 Denys Vlasenko
|
2008-02-16 22:58:56 +00:00
|
|
|
*
|
2010-08-16 18:14:46 +00:00
|
|
|
* Licensed under GPLv2, see file LICENSE in this source tree.
|
2008-02-16 22:58:56 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "libbb.h"
|
|
|
|
|
2008-09-11 19:51:11 +00:00
|
|
|
/* All known arches use small ints for signals */
|
|
|
|
smallint bb_got_signal;
|
|
|
|
|
2008-06-27 02:52:20 +00:00
|
|
|
int FAST_FUNC sigprocmask_allsigs(int how)
|
2008-03-17 08:29:08 +00:00
|
|
|
{
|
|
|
|
sigset_t set;
|
|
|
|
sigfillset(&set);
|
|
|
|
return sigprocmask(how, &set, NULL);
|
|
|
|
}
|
|
|
|
|
2014-11-25 23:43:14 +00:00
|
|
|
void FAST_FUNC bb_signals(long int sigs, sig_t f)
|
2008-02-16 22:58:56 +00:00
|
|
|
{
|
|
|
|
int sig_no = 0;
|
2014-11-25 23:43:14 +00:00
|
|
|
long int bit = 1;
|
2008-02-16 22:58:56 +00:00
|
|
|
|
|
|
|
while (sigs) {
|
|
|
|
if (sigs & bit) {
|
2012-09-27 11:20:34 +00:00
|
|
|
sigs -= bit;
|
2008-02-16 22:58:56 +00:00
|
|
|
signal(sig_no, f);
|
|
|
|
}
|
|
|
|
sig_no++;
|
|
|
|
bit <<= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-27 02:52:20 +00:00
|
|
|
void FAST_FUNC sig_unblock(int sig)
|
2008-02-16 22:58:56 +00:00
|
|
|
{
|
|
|
|
sigset_t ss;
|
|
|
|
sigemptyset(&ss);
|
|
|
|
sigaddset(&ss, sig);
|
|
|
|
sigprocmask(SIG_UNBLOCK, &ss, NULL);
|
|
|
|
}
|
|
|
|
|
2008-02-24 13:36:01 +00:00
|
|
|
/* Assuming the sig is fatal */
|
2008-06-27 02:52:20 +00:00
|
|
|
void FAST_FUNC kill_myself_with_sig(int sig)
|
2008-02-24 13:36:01 +00:00
|
|
|
{
|
|
|
|
signal(sig, SIG_DFL);
|
2008-03-12 23:13:50 +00:00
|
|
|
sig_unblock(sig);
|
2014-11-10 22:08:24 +00:00
|
|
|
signal_parent_to_resume();
|
2008-02-24 13:36:01 +00:00
|
|
|
raise(sig);
|
2012-09-27 11:20:34 +00:00
|
|
|
_exit(sig | 128); /* Should not reach it */
|
2008-02-24 13:36:01 +00:00
|
|
|
}
|
2015-01-16 00:02:33 +00:00
|
|
|
|
|
|
|
#ifdef __GNO__
|
|
|
|
/* Include our own version of sigprocmask, because the one in
|
|
|
|
* GNO 2.0.6 libc is broken for SIG_SETMASK and SIG_UNBLOCK cases
|
|
|
|
* (it will never unblock any signals). */
|
|
|
|
int sigprocmask(int how, const sigset_t *set, sigset_t *oset)
|
|
|
|
{
|
|
|
|
sigset_t oldmask;
|
|
|
|
|
|
|
|
if (set) {
|
|
|
|
switch (how) {
|
|
|
|
case SIG_BLOCK:
|
|
|
|
oldmask = sigblock(*set);
|
|
|
|
break;
|
|
|
|
case SIG_SETMASK:
|
|
|
|
oldmask = sigsetmask(*set);
|
|
|
|
break;
|
|
|
|
case SIG_UNBLOCK:
|
|
|
|
oldmask = sigblock(0);
|
|
|
|
sigsetmask(oldmask & ~*set);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else if (oset) {
|
|
|
|
oldmask = sigblock(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (oset)
|
|
|
|
*oset = oldmask;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|