drivers/pty: support pty write to send signal, like serial driver
The interaction between the shell service in adb and adbd occurs through a pseudo-terminal (pty). so, when a command is launched through adb shell from a PC, users now have the ability to pause or kill the launched,application by inputting specific commands CONFIG_TTY_SIGTSTP_CHAR or CONFIG_TTY_SIGTINT_CHAR, akin to the capabilities provided by nsh. Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
a78622d7bf
commit
d4bbbe0d0b
@ -44,6 +44,7 @@
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/serial/pty.h>
|
||||
#include <nuttx/signal.h>
|
||||
|
||||
#include "pty.h"
|
||||
|
||||
@ -77,6 +78,9 @@ struct pty_dev_s
|
||||
struct file pd_sink; /* Accepts data from write() method (pipe input) */
|
||||
bool pd_master; /* True: this is the master */
|
||||
uint8_t pd_escape; /* Number of the character to be escaped */
|
||||
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
||||
pid_t pd_pid; /* Thread PID to receive signals (-1 if none) */
|
||||
#endif
|
||||
tcflag_t pd_iflag; /* Terminal input modes */
|
||||
tcflag_t pd_lflag; /* Terminal local modes */
|
||||
tcflag_t pd_oflag; /* Terminal output modes */
|
||||
@ -540,6 +544,9 @@ static ssize_t pty_write(FAR struct file *filep,
|
||||
FAR struct pty_dev_s *dev;
|
||||
ssize_t ntotal;
|
||||
ssize_t nwritten;
|
||||
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
||||
pid_t pid;
|
||||
#endif
|
||||
size_t i;
|
||||
char ch;
|
||||
|
||||
@ -547,6 +554,14 @@ static ssize_t pty_write(FAR struct file *filep,
|
||||
dev = inode->i_private;
|
||||
DEBUGASSERT(dev != NULL);
|
||||
|
||||
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
||||
pid = dev->pd_devpair->pp_master.pd_pid;
|
||||
if (dev->pd_master)
|
||||
{
|
||||
pid = dev->pd_devpair->pp_slave.pd_pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do output post-processing */
|
||||
|
||||
if ((dev->pd_oflag & OPOST) != 0)
|
||||
@ -599,6 +614,22 @@ static ssize_t pty_write(FAR struct file *filep,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TTY_SIGINT
|
||||
if (pid > 0 && ch == CONFIG_TTY_SIGINT_CHAR)
|
||||
{
|
||||
nxsig_kill(pid, SIGINT);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TTY_SIGTSTP
|
||||
if (pid > 0 && ch == CONFIG_TTY_SIGTSTP_CHAR)
|
||||
{
|
||||
nxsig_kill(pid, SIGTSTP);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Transfer the (possibly translated) character.. This will block
|
||||
* if the sink pipe is full
|
||||
*
|
||||
@ -798,6 +829,33 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
||||
/* Make the controlling terminal of the calling process */
|
||||
|
||||
case TIOCSCTTY:
|
||||
{
|
||||
/* Save the PID of the recipient of the SIGINT signal. */
|
||||
|
||||
if ((int)arg < 0 || dev->pd_pid >= 0)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->pd_pid = (pid_t)arg;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TIOCNOTTY:
|
||||
{
|
||||
dev->pd_pid = INVALID_PROCESS_ID;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* Any unrecognized IOCTL commands will be passed to the contained
|
||||
* pipe driver.
|
||||
*
|
||||
@ -1017,6 +1075,12 @@ int pty_register2(int minor, bool susv1)
|
||||
devpair->pp_slave.pd_devpair = devpair;
|
||||
devpair->pp_slave.pd_oflag = OPOST | ONLCR;
|
||||
devpair->pp_slave.pd_lflag = ECHO;
|
||||
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
||||
/* Initialize of the task that will receive SIGINT signals. */
|
||||
|
||||
devpair->pp_master.pd_pid = INVALID_PROCESS_ID;
|
||||
devpair->pp_slave.pd_pid = INVALID_PROCESS_ID;
|
||||
#endif
|
||||
|
||||
/* Register the master device
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user