diff --git a/include/signal.h b/include/signal.h index e95cb58c7a9..f07f4d36483 100644 --- a/include/signal.h +++ b/include/signal.h @@ -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 diff --git a/sched/Kconfig b/sched/Kconfig index 949bbf6dc5e..be76593b919 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -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 diff --git a/sched/signal/sig_action.c b/sched/signal/sig_action.c index 9dd041a51fd..83c61724b56 100644 --- a/sched/signal/sig_action.c +++ b/sched/signal/sig_action.c @@ -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; diff --git a/sched/signal/sig_default.c b/sched/signal/sig_default.c index 6d99165de7a..82f77e37397 100644 --- a/sched/signal/sig_default.c +++ b/sched/signal/sig_default.c @@ -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; } diff --git a/sched/signal/signal.h b/sched/signal/signal.h index dce8961db98..e45fcfa315f 100644 --- a/sched/signal/signal.h +++ b/sched/signal/signal.h @@ -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