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
+9 -4
View File
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4"> <tr align="center" bgcolor="#e4e4e4">
<td> <td>
<h1><big><font color="#3c34ec"><i>NuttShell (NSH)</i></font></big></h1> <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> </td>
</tr> </tr>
</table> </table>
@@ -2034,11 +2034,16 @@ nsh&gt;
</pre></ul> </pre></ul>
<p><small> <p><small>
<b>NOTE</b>: <b>NOTE</b>:
NuttX does not support a FULL POSIX signalling system. NuttX does not support a FULL POSIX signaling 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. 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. 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. 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> </p></small>
<table width ="100%"> <table width ="100%">
+14 -11
View File
@@ -131,8 +131,8 @@ config SERIAL_TERMIOS
If this is not defined, then the terminal settings (baud, parity, etc). If this is not defined, then the terminal settings (baud, parity, etc).
are not configurable at runtime; serial streams cannot be flushed, etc.. are not configurable at runtime; serial streams cannot be flushed, etc..
config TTY_SIGKILL config TTY_SIGINT
bool "Support SIGKILL" bool "Support SIGINT"
default n default n
select SIG_DEFAULT select SIG_DEFAULT
depends on !DISABLE_SIGNALS && SERIAL_TERMIOS depends on !DISABLE_SIGNALS && SERIAL_TERMIOS
@@ -152,23 +152,26 @@ config TTY_SIGKILL
SUSP SIGSTP Ctrl-Z SUB(0x1a) Suspend SUSP SIGSTP Ctrl-Z SUB(0x1a) Suspend
DSUSP SIGSTP Ctrl-Y EM (0x19) Delayed suspend DSUSP SIGSTP Ctrl-Y EM (0x19) Delayed suspend
NOTES: Additional requirements:
- SIGQUIT is like SIGKILL but causes generation of a core dump - SIGKILL cannot be caught or ignored. Compared to SIGTERM which
- SIGSTP is like SIGSTOP but can be ignored. is like SIGKILL but can be caught or ignored.
- The delayed suspend (DSUS) is like suspend (SUPD), except that - 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 the suspension is delayed until the next read operation
Ctrl-D (EOT 0x04) normally should not generate a signal but, instead, 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 config TTY_SIGINT_CHAR
int "Serial parse SIGKILL characters" int "Serial parse SIGINT characters"
default 3 if SERIAL_CONSOLE default 3 if SERIAL_CONSOLE
default 4 if !SERIAL_CONSOLE default 4 if !SERIAL_CONSOLE
depends on TTY_SIGKILL depends on TTY_SIGINT
---help--- ---help---
Use ASCII 3 (Ctrl-c) or 4 (ctrl-d) inputs to determine whether to 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 REVISIT: Traditionally Ctrl-C would generate SIGINT. Ctrl-D is the
End-of-File character that should close the stream. End-of-File character that should close the stream.
+5 -5
View File
@@ -1372,7 +1372,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
break; break;
#endif #endif
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
/* Make the given terminal the controlling terminal of the calling process */ /* Make the given terminal the controlling terminal of the calling process */
case TIOCSCTTY: 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) 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; dev->pid = (pid_t)arg;
DEBUGASSERT((unsigned long)(dev->pid) == 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_oflag = termiosp->c_oflag;
dev->tc_lflag = termiosp->c_lflag; 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- /* If the ISIG flag has been cleared in c_lflag, then un-
* register the controlling terminal. * register the controlling terminal.
*/ */
@@ -1611,8 +1611,8 @@ errout:
int uart_register(FAR const char *path, FAR uart_dev_t *dev) int uart_register(FAR const char *path, FAR uart_dev_t *dev)
{ {
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
/* Initialize of the task that will receive SIGKILL signals. */ /* Initialize of the task that will receive SIGINT signals. */
dev->pid = (pid_t)-1; dev->pid = (pid_t)-1;
+16 -16
View File
@@ -53,21 +53,21 @@
************************************************************************************/ ************************************************************************************/
/************************************************************************************ /************************************************************************************
* Name: uart_check_sigkill * Name: uart_check_sigint
* *
* Description: * 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 #ifdef CONFIG_TTY_SIGINT
static bool uart_check_sigkill(const char *buf, size_t size) static bool uart_check_sigint(const char *buf, size_t size)
{ {
size_t i; size_t i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
if (buf[i] == CONFIG_TTY_SIGKILL_CHAR) if (buf[i] == CONFIG_TTY_SIGINT_CHAR)
{ {
return true; return true;
} }
@@ -81,30 +81,30 @@ static bool uart_check_sigkill(const char *buf, size_t size)
* Name: uart_recvchars_sigkill * Name: uart_recvchars_sigkill
* *
* Description: * 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. * 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) static bool uart_recvchars_sigkill(FAR uart_dev_t *dev)
{ {
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx; FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
if (xfer->nbytes <= xfer->length) if (xfer->nbytes <= xfer->length)
{ {
return uart_check_sigkill(xfer->buffer, xfer->nbytes); return uart_check_sigint(xfer->buffer, xfer->nbytes);
} }
else else
{ {
if (uart_check_sigkill(xfer->buffer, xfer->length)) if (uart_check_sigint(xfer->buffer, xfer->length))
{ {
return true; return true;
} }
return uart_check_sigkill(xfer->nbuffer, xfer->nbytes - xfer->length); return uart_check_sigint(xfer->nbuffer, xfer->nbytes - xfer->length);
} }
} }
#endif #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_dmaxfer_s *xfer = &dev->dmarx;
FAR struct uart_buffer_s *rxbuf = &dev->recv; FAR struct uart_buffer_s *rxbuf = &dev->recv;
size_t nbytes = xfer->nbytes; size_t nbytes = xfer->nbytes;
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
bool needkill = false; 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)) if (dev->pid >= 0 && uart_recvchars_sigkill(dev))
{ {
@@ -350,12 +350,12 @@ void uart_recvchars_done(FAR uart_dev_t *dev)
uart_datareceived(dev); uart_datareceived(dev);
} }
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
/* Send the SIGKILL signal if needed */ /* Send the SIGINT signal if needed */
if (needkill) if (needkill)
{ {
kill(dev->pid, SIGKILL); kill(dev->pid, SIGINT);
uart_reset_sem(dev); uart_reset_sem(dev);
} }
#endif #endif
+7 -7
View File
@@ -123,7 +123,7 @@ void uart_recvchars(FAR uart_dev_t *dev)
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS #ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
unsigned int watermark; unsigned int watermark;
#endif #endif
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
bool needkill = false; bool needkill = false;
#endif #endif
unsigned int status; unsigned int status;
@@ -201,10 +201,10 @@ void uart_recvchars(FAR uart_dev_t *dev)
ch = uart_receive(dev, &status); ch = uart_receive(dev, &status);
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
/* Is this the special character that will generate the SIGKILL signal? */ /* 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 /* 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. * 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); uart_datareceived(dev);
} }
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
/* Send the SIGKILL signal if needed */ /* Send the SIGINT signal if needed */
if (needkill) if (needkill)
{ {
kill(dev->pid, SIGKILL); kill(dev->pid, SIGINT);
uart_reset_sem(dev); uart_reset_sem(dev);
} }
#endif #endif
+2 -2
View File
@@ -286,8 +286,8 @@ struct uart_dev_s
tcflag_t tc_iflag; /* Input modes */ tcflag_t tc_iflag; /* Input modes */
tcflag_t tc_oflag; /* Output modes */ tcflag_t tc_oflag; /* Output modes */
tcflag_t tc_lflag; /* Local modes */ tcflag_t tc_lflag; /* Local modes */
#ifdef CONFIG_TTY_SIGKILL #ifdef CONFIG_TTY_SIGINT
pid_t pid; /* Thread PID to receive SIGKILL signals (-1 if none) */ pid_t pid; /* Thread PID to receive SIGINT signals (-1 if none) */
#endif #endif
#endif #endif
+6 -1
View File
@@ -170,8 +170,13 @@
#endif #endif
#ifdef CONFIG_SIG_DEFAULT #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 # 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 # else
# define SIGKILL CONFIG_SIG_KILL # define SIGKILL CONFIG_SIG_KILL
# endif # endif
+10 -1
View File
@@ -1269,13 +1269,22 @@ config SIG_POLL
The SIGPOLL signal is sent to a process when an asynchronous I/O The SIGPOLL signal is sent to a process when an asynchronous I/O
event occurs (meaning it has been polled). Default: 5 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 config SIG_KILL
int "SIGKILL" int "SIGKILL"
default 9 default 9
depends on SIG_DEFAULT depends on SIG_DEFAULT
---help--- ---help---
The SIGKILL signal is sent to cause a task termination event (only 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" comment "Non-standard Signal Numbers"
+1
View File
@@ -102,6 +102,7 @@ static const struct nxsig_defaction_s g_defactions[] =
#ifdef CONFIG_SIG_SIGPOLL_ACTION #ifdef CONFIG_SIG_SIGPOLL_ACTION
{ SIGPOLL, nxsig_abnormal_termination }, { SIGPOLL, nxsig_abnormal_termination },
#endif #endif
{ SIGINT, nxsig_abnormal_termination },
{ SIGKILL, nxsig_abnormal_termination } { SIGKILL, nxsig_abnormal_termination }
}; };