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:
parent
0756cf66ed
commit
dcb3d4b050
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user