sched/signal: Add support for SIGINT in addition to SIGKILL. drivers/serial: Use SIGINT instead of SIGKILL when control-C is pressed.

This commit is contained in:
Gregory Nutt 2018-08-28 12:15:31 -06:00
parent 0b60bbc6d3
commit 0756cf66ed
9 changed files with 70 additions and 47 deletions

View file

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttShell (NSH)</i></font></big></h1>
<p>Last Updated: August 22, 2018</p>
<p>Last Updated: August 28, 2018</p>
</td>
</tr>
</table>
@ -2034,11 +2034,16 @@ nsh&gt;
</pre></ul>
<p><small>
<b>NOTE</b>:
NuttX does not support a FULL POSIX signalling system.
Standard signals like SIGCHLD, SIGINTR, SIGKILL, etc. do not exist in NuttX and sending those signals may not have the result that you expect.
NuttX does not support a FULL POSIX signaling system.
A few standard signal names like <code>SIGCHLD</code>, <code>SIGUSR1</code>, <code>SIGUSR2</code>, <code>SIGALRM</code>, and <code>SIGPOLL</code> exist in the system.
However, they do not have the default actions that you might expect.
Rather, NuttX supports only what are referred to as POSIX real-time signals.
These signals may be used to communicate with running tasks, may be use to waiting waiting tasks, etc.
But, as an example, <code>kill -9</code> (SIGKILL) will not terminate a task.
</p>
<p>
If the configuration option <code>CONFIG_SIG_DEFAULT</code> is enabled, then default actions for the <code>SIGINT</code> and <code>SIGKILL</code> signals (only) will be supported.
In that case, as an example, <code>kill -9</code> (SIGKILL) will, indeed, terminate a task.
Caution should be exercised, however, because this is likely to cause memory leaks and to strand resource since there is insufficient clean-up in certain build configurations.
</p></small>
<table width ="100%">

View file

@ -131,8 +131,8 @@ config SERIAL_TERMIOS
If this is not defined, then the terminal settings (baud, parity, etc).
are not configurable at runtime; serial streams cannot be flushed, etc..
config TTY_SIGKILL
bool "Support SIGKILL"
config TTY_SIGINT
bool "Support SIGINT"
default n
select SIG_DEFAULT
depends on !DISABLE_SIGNALS && SERIAL_TERMIOS
@ -152,23 +152,26 @@ config TTY_SIGKILL
SUSP SIGSTP Ctrl-Z SUB(0x1a) Suspend
DSUSP SIGSTP Ctrl-Y EM (0x19) Delayed suspend
NOTES:
- SIGQUIT is like SIGKILL but causes generation of a core dump
- SIGSTP is like SIGSTOP but can be ignored.
- The delayed suspend (DSUS) is like suspend (SUPD), except that
Additional requirements:
- SIGKILL cannot be caught or ignored. Compared to SIGTERM which
is like SIGKILL but can be caught or ignored.
- SIGQUIT is like SIGINT but causes generation of a core dump
- SIGSTOP cannot be caught or ignored. SIGSTP is like SIGSTOP but
can be caught or ignored ignored.
- The delayed suspend (DSUSD) is like suspend (SUPD), except that
the suspension is delayed until the next read operation
Ctrl-D (EOT 0x04) normally should not generate a signal but, instead,
should generate an immediate End-of-File result.
should cause an immediate End-of-File result.
config TTY_SIGKILL_CHAR
int "Serial parse SIGKILL characters"
config TTY_SIGINT_CHAR
int "Serial parse SIGINT characters"
default 3 if SERIAL_CONSOLE
default 4 if !SERIAL_CONSOLE
depends on TTY_SIGKILL
depends on TTY_SIGINT
---help---
Use ASCII 3 (Ctrl-c) or 4 (ctrl-d) inputs to determine whether to
send a SIGKILL event. Other characters may also be selected.
send a SIGINT event. Other characters may also be selected.
REVISIT: Traditionally Ctrl-C would generate SIGINT. Ctrl-D is the
End-of-File character that should close the stream.

View file

@ -1372,7 +1372,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
break;
#endif
#ifdef CONFIG_TTY_SIGKILL
#ifdef CONFIG_TTY_SIGINT
/* Make the given terminal the controlling terminal of the calling process */
case TIOCSCTTY:
@ -1384,7 +1384,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if ((dev->tc_lflag & ISIG) != 0)
{
/* Save the PID of the recipient of the SIGKILL signal. */
/* Save the PID of the recipient of the SIGINT signal. */
dev->pid = (pid_t)arg;
DEBUGASSERT((unsigned long)(dev->pid) == arg);
@ -1436,7 +1436,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
dev->tc_oflag = termiosp->c_oflag;
dev->tc_lflag = termiosp->c_lflag;
#ifdef CONFIG_TTY_SIGKILL
#ifdef CONFIG_TTY_SIGINT
/* If the ISIG flag has been cleared in c_lflag, then un-
* register the controlling terminal.
*/
@ -1611,8 +1611,8 @@ errout:
int uart_register(FAR const char *path, FAR uart_dev_t *dev)
{
#ifdef CONFIG_TTY_SIGKILL
/* Initialize of the task that will receive SIGKILL signals. */
#ifdef CONFIG_TTY_SIGINT
/* Initialize of the task that will receive SIGINT signals. */
dev->pid = (pid_t)-1;

View file

@ -53,21 +53,21 @@
************************************************************************************/
/************************************************************************************
* Name: uart_check_sigkill
* Name: uart_check_sigint
*
* Description:
* Check if the SIGKILL character is in the contiguous Rx DMA buffer region.
* Check if the SIGINT character is in the contiguous Rx DMA buffer region.
*
************************************************************************************/
#ifdef CONFIG_TTY_SIGKILL
static bool uart_check_sigkill(const char *buf, size_t size)
#ifdef CONFIG_TTY_SIGINT
static bool uart_check_sigint(const char *buf, size_t size)
{
size_t i;
for (i = 0; i < size; i++)
{
if (buf[i] == CONFIG_TTY_SIGKILL_CHAR)
if (buf[i] == CONFIG_TTY_SIGINT_CHAR)
{
return true;
}
@ -81,30 +81,30 @@ static bool uart_check_sigkill(const char *buf, size_t size)
* Name: uart_recvchars_sigkill
*
* Description:
* Check if the SIGKILL character is anywhere in the newly received DMA buffer.
* Check if the SIGINT character is anywhere in the newly received DMA buffer.
*
* REVISIT: We must also remove the SIGKILL character from the Rx buffer. It
* REVISIT: We must also remove the SIGINT character from the Rx buffer. It
* should not be read as normal data by the caller.
*
************************************************************************************/
#ifdef CONFIG_TTY_SIGKILL
#ifdef CONFIG_TTY_SIGINT
static bool uart_recvchars_sigkill(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
if (xfer->nbytes <= xfer->length)
{
return uart_check_sigkill(xfer->buffer, xfer->nbytes);
return uart_check_sigint(xfer->buffer, xfer->nbytes);
}
else
{
if (uart_check_sigkill(xfer->buffer, xfer->length))
if (uart_check_sigint(xfer->buffer, xfer->length))
{
return true;
}
return uart_check_sigkill(xfer->nbuffer, xfer->nbytes - xfer->length);
return uart_check_sigint(xfer->nbuffer, xfer->nbytes - xfer->length);
}
}
#endif
@ -324,10 +324,10 @@ void uart_recvchars_done(FAR uart_dev_t *dev)
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
FAR struct uart_buffer_s *rxbuf = &dev->recv;
size_t nbytes = xfer->nbytes;
#ifdef CONFIG_TTY_SIGKILL
#ifdef CONFIG_TTY_SIGINT
bool needkill = false;
/* Check if the SIGKILL character is anywhere in the newly received DMA buffer. */
/* Check if the SIGINT character is anywhere in the newly received DMA buffer. */
if (dev->pid >= 0 && uart_recvchars_sigkill(dev))
{
@ -350,12 +350,12 @@ void uart_recvchars_done(FAR uart_dev_t *dev)
uart_datareceived(dev);
}
#ifdef CONFIG_TTY_SIGKILL
/* Send the SIGKILL signal if needed */
#ifdef CONFIG_TTY_SIGINT
/* Send the SIGINT signal if needed */
if (needkill)
{
kill(dev->pid, SIGKILL);
kill(dev->pid, SIGINT);
uart_reset_sem(dev);
}
#endif

View file

@ -123,7 +123,7 @@ void uart_recvchars(FAR uart_dev_t *dev)
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
unsigned int watermark;
#endif
#ifdef CONFIG_TTY_SIGKILL
#ifdef CONFIG_TTY_SIGINT
bool needkill = false;
#endif
unsigned int status;
@ -201,10 +201,10 @@ void uart_recvchars(FAR uart_dev_t *dev)
ch = uart_receive(dev, &status);
#ifdef CONFIG_TTY_SIGKILL
/* Is this the special character that will generate the SIGKILL signal? */
#ifdef CONFIG_TTY_SIGINT
/* Is this the special character that will generate the SIGINT signal? */
if (dev->pid >= 0 && ch == CONFIG_TTY_SIGKILL_CHAR)
if (dev->pid >= 0 && ch == CONFIG_TTY_SIGINT_CHAR)
{
/* Yes.. note that the kill is needed and do not put the character
* into the Rx buffer. It should not be read as normal data.
@ -249,12 +249,12 @@ void uart_recvchars(FAR uart_dev_t *dev)
uart_datareceived(dev);
}
#ifdef CONFIG_TTY_SIGKILL
/* Send the SIGKILL signal if needed */
#ifdef CONFIG_TTY_SIGINT
/* Send the SIGINT signal if needed */
if (needkill)
{
kill(dev->pid, SIGKILL);
kill(dev->pid, SIGINT);
uart_reset_sem(dev);
}
#endif

View file

@ -286,8 +286,8 @@ struct uart_dev_s
tcflag_t tc_iflag; /* Input modes */
tcflag_t tc_oflag; /* Output modes */
tcflag_t tc_lflag; /* Local modes */
#ifdef CONFIG_TTY_SIGKILL
pid_t pid; /* Thread PID to receive SIGKILL signals (-1 if none) */
#ifdef CONFIG_TTY_SIGINT
pid_t pid; /* Thread PID to receive SIGINT signals (-1 if none) */
#endif
#endif

View file

@ -170,8 +170,13 @@
#endif
#ifdef CONFIG_SIG_DEFAULT
# ifndef CONFIG_SIG_INT
# define SIGINT 6 /* Sent when ctrl-c event */
# else
# define SIGINT CONFIG_SIG_INT
# endif
# ifndef CONFIG_SIG_KILL
# define SIGKILL 9 /* Sent when ctrl-c event (vs. standard SIGINT) */
# define SIGKILL 9 /* Sent from shell as 'kill -9 <task>' */
# else
# define SIGKILL CONFIG_SIG_KILL
# endif

View file

@ -1269,13 +1269,22 @@ config SIG_POLL
The SIGPOLL signal is sent to a process when an asynchronous I/O
event occurs (meaning it has been polled). Default: 5
config SIG_INT
int "SIGINT"
default 6
depends on SIG_DEFAULT
---help---
The SIGINT signal is sent to cause a task termination event (only
if CONFIG_SIG_DEFAULT=y). SIGINT may be ignored or caught by the
receiving task.
config SIG_KILL
int "SIGKILL"
default 9
depends on SIG_DEFAULT
---help---
The SIGKILL signal is sent to cause a task termination event (only
if CONFIG_SIG_DEFAULT=y)
if CONFIG_SIG_DEFAULT=y). SIGKILL may not be caught or ignored.
comment "Non-standard Signal Numbers"

View file

@ -102,6 +102,7 @@ static const struct nxsig_defaction_s g_defactions[] =
#ifdef CONFIG_SIG_SIGPOLL_ACTION
{ SIGPOLL, nxsig_abnormal_termination },
#endif
{ SIGINT, nxsig_abnormal_termination },
{ SIGKILL, nxsig_abnormal_termination }
};