sched/signal: Add logic and an interface to determin if a signal can be caught or ignored. sigaction now correctly returns EINVAL on any attempt to catch or ignore such signals (only SIGKILL for now and only if CONFIG_SIG_DEFAULT=y).

This commit is contained in:
Gregory Nutt 2018-08-28 12:39:03 -06:00
parent 0756cf66ed
commit dcb3d4b050
4 changed files with 71 additions and 12 deletions

View File

@ -141,10 +141,10 @@ config TTY_SIGINT
devices. May be enabled for other serial devices using the ISIG bit
in the Termios c_lflag.
REVISIT: This implementation is non-standard. The c_lflag ISIG bit
normally enables/disables INTR, QUIT, SUSP, and DSUSP character
processing. The relationship between these names, standard signals,
and typical key presses are as follows:
REVISIT: This implementation is compliant but incomplete. The
c_lflag ISIG bit normally enables/disables INTR, QUIT, SUSP, and
DSUSP character processing. The relationship between these names,
standard signals, and typical key presses are as follows:
INTR SIGINT Ctrl-C ETX(0x03) Interrupt
KILL SIGKILL Ctrl-U NAK(0x15) Kill

View File

@ -137,8 +137,8 @@ static FAR sigactq_t *nxsig_alloc_action(void)
* Assumptions:
*
* POSIX Compatibility:
* - There are no default actions so the special value SIG_DFL is treated
* like SIG_IGN.
* - If CONFIG_SIG_DEFAULT is not defined, then there are no default actions
* so the special value SIG_DFL is treated like SIG_IGN.
* - All sa_flags in struct sigaction of act input are ignored (all
* treated like SA_SIGINFO). The one exception is if CONFIG_SCHED_CHILD_STATUS
* is defined; then SA_NOCLDWAIT is supported but only for SIGCHLD
@ -168,6 +168,19 @@ int sigaction(int signo, FAR const struct sigaction *act,
return ERROR;
}
#ifdef CONFIG_SIG_DEFAULT
/* Check if the user is trying to catch or ignore a signal that cannot be
* caught or ignored.
*/
if (act != NULL &&
(act->sa_handler != SIG_DFL && !nxsig_iscatchable(signo)))
{
set_errno(EINVAL);
return ERROR;
}
#endif
/* Find the signal in the signal action queue */
sigact = nxsig_find_action(group, signo);

View File

@ -48,6 +48,14 @@
#include "signal/signal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Bit definitions for the struct nxsig_defaction_s 'flags' field */
#define SIG_FLAG_NOCATCH (1 << 0) /* Signal cannot be caught or ignored */
/****************************************************************************
* Private Types
****************************************************************************/
@ -57,6 +65,7 @@
struct nxsig_defaction_s
{
uint8_t signo; /* Signal number. Range 1..MAX_SIGNO */
uint8_t flags; /* See SIG_FLAG_ definitions */
_sa_handler_t action; /* Default signal action */
};
@ -91,19 +100,19 @@ static void nxsig_setup_default_action(FAR struct task_group_s *group,
static const struct nxsig_defaction_s g_defactions[] =
{
#ifdef CONFIG_SIG_SIGUSR1_ACTION
{ SIGUSR1, nxsig_abnormal_termination },
{ SIGUSR1, 0, nxsig_abnormal_termination },
#endif
#ifdef CONFIG_SIG_SIGUSR2_ACTION
{ SIGUSR2, nxsig_abnormal_termination },
{ SIGUSR2, 0, nxsig_abnormal_termination },
#endif
#ifdef CONFIG_SIG_SIGALRM_ACTION
{ SIGALRM, nxsig_abnormal_termination },
{ SIGALRM, 0, nxsig_abnormal_termination },
#endif
#ifdef CONFIG_SIG_SIGPOLL_ACTION
{ SIGPOLL, nxsig_abnormal_termination },
{ SIGPOLL, 0, nxsig_abnormal_termination },
#endif
{ SIGINT, nxsig_abnormal_termination },
{ SIGKILL, nxsig_abnormal_termination }
{ SIGINT, 0, nxsig_abnormal_termination },
{ SIGKILL, SIG_FLAG_NOCATCH, nxsig_abnormal_termination }
};
#define NACTIONS (sizeof(g_defactions) / sizeof(struct nxsig_defaction_s))
@ -272,6 +281,42 @@ bool nxsig_isdefault(FAR struct tcb_s *tcb, int signo)
return ret < 0 ? false : (bool)ret;
}
/****************************************************************************
* Name: nxsig_iscatchable
*
* Description:
* Return true if the specified signal can be caught or ignored.
*
* Input Parameters:
* signo - The signal number to be queried
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned
* on failure.
*
****************************************************************************/
bool nxsig_iscatchable(int signo)
{
int i;
/* 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].flags & SIG_FLAG_NOCATCH) == 0;
}
}
/* If it is not in the table, then it is catchable */
return true;
}
/****************************************************************************
* Name: nxsig_default
*

View File

@ -174,6 +174,7 @@ void nxsig_release_action(FAR sigactq_t *sigact);
#ifdef CONFIG_SIG_DEFAULT
bool nxsig_isdefault(FAR struct tcb_s *tcb, int signo);
bool nxsig_iscatchable(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);