sched/signal: Default Signal Actions. Change some types to superficially simplify. Add configuration options to enabled default signal behaviors on a per-signal basis. I don't think users are prepared for SIGALRM to terminate the task (which is the correct default behavior if you don't change it). Extend the implementation of default signals so that it is totally table driven and extensible by simply mondifying the content of const tables.
This commit is contained in:
parent
a02f919bec
commit
499b89feed
@ -146,11 +146,11 @@
|
||||
# define SIGUSR2 CONFIG_SIG_SIGUSR2
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SIG_SIGALARM
|
||||
#ifndef CONFIG_SIG_SIGALRM
|
||||
# define SIGALRM 3 /* Default signal used with POSIX timers (used only */
|
||||
/* no other signal is provided) */
|
||||
#else
|
||||
# define SIGALRM CONFIG_SIG_SIGALARM
|
||||
# define SIGALRM CONFIG_SIG_SIGALRM
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
|
@ -1186,18 +1186,53 @@ config SIG_EVTHREAD
|
||||
different mechanism would need to be development to support this
|
||||
feature on the PROTECTED or KERNEL build.
|
||||
|
||||
config SIG_DEFAULT
|
||||
menuconfig SIG_DEFAULT
|
||||
bool "Default signal actions"
|
||||
default n
|
||||
depends on !DISABLE_SIGNALS
|
||||
---help---
|
||||
Enable to support default signal actions.
|
||||
|
||||
NOTE: SIGKILL is the only signal currently supported.
|
||||
if SIG_DEFAULT
|
||||
|
||||
comment "Per-signal Default Actions"
|
||||
|
||||
config SIG_SIGUSR1_ACTION
|
||||
bool "SIGUSR1"
|
||||
default n
|
||||
---help---
|
||||
Enable the default action for SIGUSR1 (terminate the process)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
|
||||
config SIG_SIGUSR2_ACTION
|
||||
bool "SIGUSR2"
|
||||
default n
|
||||
---help---
|
||||
Enable the default action for SIGUSR2 (terminate the process)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
|
||||
config SIG_SIGALRM_ACTION
|
||||
bool "SIGALRM"
|
||||
default n
|
||||
---help---
|
||||
Enable the default action for SIGALRM (terminate the process)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
|
||||
config SIG_SIGPOLL_ACTION
|
||||
bool "SIGPOLL"
|
||||
default n
|
||||
depends on FS_AIO
|
||||
---help---
|
||||
Enable the default action for SIGPOLL (terminate the process)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
|
||||
endif # SIG_DEFAULT
|
||||
|
||||
menu "Signal Numbers"
|
||||
depends on !DISABLE_SIGNALS
|
||||
|
||||
comment "Standard Signal Numbers"
|
||||
|
||||
config SIG_SIGUSR1
|
||||
int "SIGUSR1"
|
||||
default 1
|
||||
@ -1210,7 +1245,7 @@ config SIG_SIGUSR2
|
||||
---help---
|
||||
Value of standard user signal 2 (SIGUSR2). Default: 2
|
||||
|
||||
config SIG_SIGALARM
|
||||
config SIG_SIGALRM
|
||||
int "SIGALRM"
|
||||
default 3
|
||||
---help---
|
||||
@ -1242,6 +1277,8 @@ config SIG_KILL
|
||||
The SIGKILL signal is sent to cause a task termination event (only
|
||||
if CONFIG_SIG_DEFAULT=y)
|
||||
|
||||
comment "Non-standard Signal Numbers"
|
||||
|
||||
config SIG_SIGCONDTIMEDOUT
|
||||
int "SIGCONDTIMEDOUT"
|
||||
default 16
|
||||
|
@ -151,7 +151,7 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
FAR struct task_group_s *group;
|
||||
FAR sigactq_t *sigact;
|
||||
_sa_sigaction_t handler;
|
||||
_sa_handler_t handler;
|
||||
|
||||
/* Since sigactions can only be installed from the running thread of
|
||||
* execution, no special precautions should be necessary.
|
||||
@ -181,9 +181,9 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
{
|
||||
/* Return SIG_DFL if the default signal is attached */
|
||||
|
||||
oact->sa_sigaction = (_sa_sigaction_t)SIG_DFL;
|
||||
oact->sa_mask = NULL_SIGNAL_SET;
|
||||
oact->sa_flags = SA_SIGINFO;
|
||||
oact->sa_handler = SIG_DFL;
|
||||
oact->sa_mask = NULL_SIGNAL_SET;
|
||||
oact->sa_flags = SA_SIGINFO;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -191,17 +191,17 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
{
|
||||
/* Return the old signal action */
|
||||
|
||||
oact->sa_sigaction = sigact->act.sa_sigaction;
|
||||
oact->sa_mask = sigact->act.sa_mask;
|
||||
oact->sa_flags = sigact->act.sa_flags;
|
||||
oact->sa_handler = sigact->act.sa_handler;
|
||||
oact->sa_mask = sigact->act.sa_mask;
|
||||
oact->sa_flags = sigact->act.sa_flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There isn't an old value */
|
||||
|
||||
oact->sa_sigaction = NULL;
|
||||
oact->sa_mask = NULL_SIGNAL_SET;
|
||||
oact->sa_flags = 0;
|
||||
oact->sa_handler = NULL;
|
||||
oact->sa_mask = NULL_SIGNAL_SET;
|
||||
oact->sa_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,14 +246,14 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
}
|
||||
#endif
|
||||
|
||||
handler = act->sa_sigaction;
|
||||
handler = act->sa_handler;
|
||||
|
||||
#ifdef CONFIG_SIG_DEFAULT
|
||||
/* If the caller is setting the handler to SIG_DFL, then we need to
|
||||
* replace this with the correct, internal default signal action handler.
|
||||
*/
|
||||
|
||||
if (handler == (_sa_sigaction_t)SIG_DFL)
|
||||
if (handler == SIG_DFL)
|
||||
{
|
||||
/* nxsig_default() may returned SIG_IGN */
|
||||
|
||||
@ -269,7 +269,7 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
|
||||
/* Handle the case where no sigaction is supplied (SIG_IGN) */
|
||||
|
||||
if (handler == (_sa_sigaction_t)SIG_IGN)
|
||||
if (handler == SIG_IGN)
|
||||
{
|
||||
/* Do we still have a sigaction container from the previous setting? */
|
||||
|
||||
@ -318,9 +318,9 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
|
||||
/* Set the new sigaction */
|
||||
|
||||
sigact->act.sa_sigaction = handler;
|
||||
sigact->act.sa_mask = act->sa_mask;
|
||||
sigact->act.sa_flags = act->sa_flags;
|
||||
sigact->act.sa_handler = handler;
|
||||
sigact->act.sa_mask = act->sa_mask;
|
||||
sigact->act.sa_flags = act->sa_flags;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -47,20 +47,64 @@
|
||||
|
||||
#include "signal/signal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This type provides the default action associated with a signal */
|
||||
|
||||
struct nxsig_defaction_s
|
||||
{
|
||||
uint8_t signo; /* Signal number. Range 1..MAX_SIGNO */
|
||||
_sa_handler_t action; /* Default signal action */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Default actions */
|
||||
|
||||
static void nxsig_abnormal_termination(int signo);
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static _sa_handler_t nxsig_default_action(int signo);
|
||||
static void nxsig_setup_default_action(FAR struct task_group_s *group,
|
||||
FAR const struct nxsig_defaction_s *info);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This table is used to make the default action for a signal to the correct
|
||||
* signal handler.
|
||||
/* NOTE: Default actions are not currently supported for very many signals.
|
||||
* However, this array is set up to support an indefinite number of default
|
||||
* signal actions.
|
||||
*/
|
||||
|
||||
#if 0 /* Not used */
|
||||
static const struct _sa_sigaction_t g_defactions[MAX_SIGNO + 1] =
|
||||
/* This table is used to make the default action for a signal to the correct
|
||||
* signal handler. Signals whose default action is be ignored do not need
|
||||
* to be in this table (e.g., SIGCHLD).
|
||||
*/
|
||||
|
||||
static const struct nxsig_defaction_s g_defactions[] =
|
||||
{
|
||||
/* To be provided */
|
||||
}
|
||||
#ifdef CONFIG_SIG_SIGUSR1_ACTION
|
||||
{ SIGUSR1, nxsig_abnormal_termination },
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGUSR2_ACTION
|
||||
{ SIGUSR2, nxsig_abnormal_termination },
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGALRM_ACTION
|
||||
{ SIGALRM, nxsig_abnormal_termination },
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGPOLL_ACTION
|
||||
{ SIGPOLL, nxsig_abnormal_termination },
|
||||
#endif
|
||||
{ SIGKILL, nxsig_abnormal_termination }
|
||||
};
|
||||
|
||||
#define NACTIONS (sizeof(g_defactions) / sizeof(struct nxsig_defaction_s))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@ -96,8 +140,7 @@ static const struct _sa_sigaction_t g_defactions[MAX_SIGNO + 1] =
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void nxsig_abnormal_termination(int signo, FAR siginfo_t *siginfo,
|
||||
FAR void *arg)
|
||||
static void nxsig_abnormal_termination(int signo)
|
||||
{
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
FAR struct tcb_s *tcb = (FAR struct tcb_s *)this_task();
|
||||
@ -126,15 +169,25 @@ static void nxsig_abnormal_termination(int signo, FAR siginfo_t *siginfo,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static _sa_sigaction_t nxsig_default_action(int signo)
|
||||
static _sa_handler_t nxsig_default_action(int signo)
|
||||
{
|
||||
#if 0 /* Not implemented */
|
||||
return g_defactions[signo];
|
||||
#else
|
||||
/* Currently only SIGKILL and the abnormal exit signal action are supported */
|
||||
int i;
|
||||
|
||||
return signo == SIGKILL ? nxsig_abnormal_termination : NULL;
|
||||
#endif
|
||||
/* Search the default action table for the entry associated with this
|
||||
* signal.
|
||||
*/
|
||||
|
||||
for (i = 0; i < NACTIONS; i++)
|
||||
{
|
||||
if (g_defactions[i].signo == signo)
|
||||
{
|
||||
return g_defactions[i].action;
|
||||
}
|
||||
}
|
||||
|
||||
/* No default action */
|
||||
|
||||
return SIG_IGN;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -154,28 +207,27 @@ static _sa_sigaction_t nxsig_default_action(int signo)
|
||||
****************************************************************************/
|
||||
|
||||
static void nxsig_setup_default_action(FAR struct task_group_s *group,
|
||||
int signo)
|
||||
FAR const struct nxsig_defaction_s *info)
|
||||
{
|
||||
struct sigaction sa;
|
||||
_sa_sigaction_t action;
|
||||
|
||||
DEBUGASSERT(group != NULL && GOOD_SIGNO(signo));
|
||||
|
||||
/* Get the address of the handler for this signals default action. */
|
||||
|
||||
action = nxsig_default_action(signo);
|
||||
if (action != (_sa_sigaction_t)SIG_IGN)
|
||||
if (info->action != SIG_IGN)
|
||||
{
|
||||
/* Attach the signal handler */
|
||||
struct sigaction sa;
|
||||
|
||||
/* Attach the signal handler.
|
||||
*
|
||||
* NOTE: sigaction will call nxsig_default(tcb, action, false)
|
||||
*/
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_sigaction = action;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_handler = info->action;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
(void)sigaction(SIGKILL, &sa, NULL);
|
||||
|
||||
/* Indicate that the default signal handler has been attached */
|
||||
|
||||
(void)sigaddset(&group->tg_sigdefault, signo);
|
||||
(void)sigaddset(&group->tg_sigdefault, (int)info->signo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,11 +291,10 @@ bool nxsig_isdefault(FAR struct tcb_s *tcb, int signo)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
_sa_sigaction_t nxsig_default(FAR struct tcb_s *tcb, int signo,
|
||||
bool defaction)
|
||||
_sa_handler_t nxsig_default(FAR struct tcb_s *tcb, int signo, bool defaction)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
_sa_sigaction_t handler = (_sa_sigaction_t)SIG_IGN;
|
||||
_sa_handler_t handler = SIG_IGN;
|
||||
|
||||
DEBUGASSERT(tcb != NULL && tcb->group != NULL);
|
||||
group = tcb->group;
|
||||
@ -257,13 +308,13 @@ bool nxsig_isdefault(FAR struct tcb_s *tcb, int signo)
|
||||
*/
|
||||
|
||||
handler = nxsig_default_action(signo);
|
||||
if (handler != (_sa_sigaction_t)SIG_IGN)
|
||||
if (handler != SIG_IGN)
|
||||
{
|
||||
(void)sigaddset(&group->tg_sigdefault, signo);
|
||||
}
|
||||
}
|
||||
|
||||
if (handler == (_sa_sigaction_t)SIG_IGN)
|
||||
if (handler == SIG_IGN)
|
||||
{
|
||||
/* We are unsetting the default action */
|
||||
|
||||
@ -292,6 +343,7 @@ bool nxsig_isdefault(FAR struct tcb_s *tcb, int signo)
|
||||
int nxsig_default_initialize(FAR struct tcb_s *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(tcb != NULL && tcb->group != NULL);
|
||||
group = tcb->group;
|
||||
@ -300,22 +352,15 @@ int nxsig_default_initialize(FAR struct tcb_s *tcb)
|
||||
|
||||
(void)sigemptyset(&group->tg_sigdefault);
|
||||
|
||||
#if 0
|
||||
/* TODO Currently only SIGKILL is supported. The following needs to be
|
||||
* in a loop that instantiates the default action for all signals (other
|
||||
* that those that are ignored).
|
||||
*/
|
||||
|
||||
for (signo = 0; signo <= MAX_SIGNO; signo++)
|
||||
for (i = 0; i < NACTIONS; i++)
|
||||
{
|
||||
nxsig_setup_default_action(group, signo);
|
||||
nxsig_setup_default_action(group, &g_defactions[i]);
|
||||
}
|
||||
|
||||
#else
|
||||
/* For now */
|
||||
|
||||
nxsig_setup_default_action(group, SIGKILL);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ void nxsig_release_action(FAR sigactq_t *sigact);
|
||||
|
||||
#ifdef CONFIG_SIG_DEFAULT
|
||||
bool nxsig_isdefault(FAR struct tcb_s *tcb, int signo);
|
||||
_sa_sigaction_t nxsig_default(FAR struct tcb_s *tcb, int signo,
|
||||
_sa_handler_t nxsig_default(FAR struct tcb_s *tcb, int signo,
|
||||
bool defaction);
|
||||
int nxsig_default_initialize(FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user