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
|
devices. May be enabled for other serial devices using the ISIG bit
|
||||||
in the Termios c_lflag.
|
in the Termios c_lflag.
|
||||||
|
|
||||||
REVISIT: This implementation is non-standard. The c_lflag ISIG bit
|
REVISIT: This implementation is compliant but incomplete. The
|
||||||
normally enables/disables INTR, QUIT, SUSP, and DSUSP character
|
c_lflag ISIG bit normally enables/disables INTR, QUIT, SUSP, and
|
||||||
processing. The relationship between these names, standard signals,
|
DSUSP character processing. The relationship between these names,
|
||||||
and typical key presses are as follows:
|
standard signals, and typical key presses are as follows:
|
||||||
|
|
||||||
INTR SIGINT Ctrl-C ETX(0x03) Interrupt
|
INTR SIGINT Ctrl-C ETX(0x03) Interrupt
|
||||||
KILL SIGKILL Ctrl-U NAK(0x15) Kill
|
KILL SIGKILL Ctrl-U NAK(0x15) Kill
|
||||||
|
@ -137,8 +137,8 @@ static FAR sigactq_t *nxsig_alloc_action(void)
|
|||||||
* Assumptions:
|
* Assumptions:
|
||||||
*
|
*
|
||||||
* POSIX Compatibility:
|
* POSIX Compatibility:
|
||||||
* - There are no default actions so the special value SIG_DFL is treated
|
* - If CONFIG_SIG_DEFAULT is not defined, then there are no default actions
|
||||||
* like SIG_IGN.
|
* so the special value SIG_DFL is treated like SIG_IGN.
|
||||||
* - All sa_flags in struct sigaction of act input are ignored (all
|
* - 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
|
* treated like SA_SIGINFO). The one exception is if CONFIG_SCHED_CHILD_STATUS
|
||||||
* is defined; then SA_NOCLDWAIT is supported but only for SIGCHLD
|
* 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;
|
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 */
|
/* Find the signal in the signal action queue */
|
||||||
|
|
||||||
sigact = nxsig_find_action(group, signo);
|
sigact = nxsig_find_action(group, signo);
|
||||||
|
@ -48,6 +48,14 @@
|
|||||||
|
|
||||||
#include "signal/signal.h"
|
#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
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -57,6 +65,7 @@
|
|||||||
struct nxsig_defaction_s
|
struct nxsig_defaction_s
|
||||||
{
|
{
|
||||||
uint8_t signo; /* Signal number. Range 1..MAX_SIGNO */
|
uint8_t signo; /* Signal number. Range 1..MAX_SIGNO */
|
||||||
|
uint8_t flags; /* See SIG_FLAG_ definitions */
|
||||||
_sa_handler_t action; /* Default signal action */
|
_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[] =
|
static const struct nxsig_defaction_s g_defactions[] =
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SIG_SIGUSR1_ACTION
|
#ifdef CONFIG_SIG_SIGUSR1_ACTION
|
||||||
{ SIGUSR1, nxsig_abnormal_termination },
|
{ SIGUSR1, 0, nxsig_abnormal_termination },
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SIG_SIGUSR2_ACTION
|
#ifdef CONFIG_SIG_SIGUSR2_ACTION
|
||||||
{ SIGUSR2, nxsig_abnormal_termination },
|
{ SIGUSR2, 0, nxsig_abnormal_termination },
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SIG_SIGALRM_ACTION
|
#ifdef CONFIG_SIG_SIGALRM_ACTION
|
||||||
{ SIGALRM, nxsig_abnormal_termination },
|
{ SIGALRM, 0, nxsig_abnormal_termination },
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SIG_SIGPOLL_ACTION
|
#ifdef CONFIG_SIG_SIGPOLL_ACTION
|
||||||
{ SIGPOLL, nxsig_abnormal_termination },
|
{ SIGPOLL, 0, nxsig_abnormal_termination },
|
||||||
#endif
|
#endif
|
||||||
{ SIGINT, nxsig_abnormal_termination },
|
{ SIGINT, 0, nxsig_abnormal_termination },
|
||||||
{ SIGKILL, nxsig_abnormal_termination }
|
{ SIGKILL, SIG_FLAG_NOCATCH, nxsig_abnormal_termination }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NACTIONS (sizeof(g_defactions) / sizeof(struct nxsig_defaction_s))
|
#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;
|
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
|
* Name: nxsig_default
|
||||||
*
|
*
|
||||||
|
@ -174,6 +174,7 @@ void nxsig_release_action(FAR sigactq_t *sigact);
|
|||||||
|
|
||||||
#ifdef CONFIG_SIG_DEFAULT
|
#ifdef CONFIG_SIG_DEFAULT
|
||||||
bool nxsig_isdefault(FAR struct tcb_s *tcb, int signo);
|
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,
|
_sa_handler_t nxsig_default(FAR struct tcb_s *tcb, int signo,
|
||||||
bool defaction);
|
bool defaction);
|
||||||
int nxsig_default_initialize(FAR struct tcb_s *tcb);
|
int nxsig_default_initialize(FAR struct tcb_s *tcb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user