mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 21:36:28 +08:00
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:
@@ -44,6 +44,7 @@
|
|||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/serial/pty.h>
|
#include <nuttx/serial/pty.h>
|
||||||
|
#include <nuttx/signal.h>
|
||||||
|
|
||||||
#include "pty.h"
|
#include "pty.h"
|
||||||
|
|
||||||
@@ -77,6 +78,9 @@ struct pty_dev_s
|
|||||||
struct file pd_sink; /* Accepts data from write() method (pipe input) */
|
struct file pd_sink; /* Accepts data from write() method (pipe input) */
|
||||||
bool pd_master; /* True: this is the master */
|
bool pd_master; /* True: this is the master */
|
||||||
uint8_t pd_escape; /* Number of the character to be escaped */
|
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_iflag; /* Terminal input modes */
|
||||||
tcflag_t pd_lflag; /* Terminal local modes */
|
tcflag_t pd_lflag; /* Terminal local modes */
|
||||||
tcflag_t pd_oflag; /* Terminal output 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;
|
FAR struct pty_dev_s *dev;
|
||||||
ssize_t ntotal;
|
ssize_t ntotal;
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
|
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGTSTP)
|
||||||
|
pid_t pid;
|
||||||
|
#endif
|
||||||
size_t i;
|
size_t i;
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
@@ -547,6 +554,14 @@ static ssize_t pty_write(FAR struct file *filep,
|
|||||||
dev = inode->i_private;
|
dev = inode->i_private;
|
||||||
DEBUGASSERT(dev != NULL);
|
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 */
|
/* Do output post-processing */
|
||||||
|
|
||||||
if ((dev->pd_oflag & OPOST) != 0)
|
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
|
/* Transfer the (possibly translated) character.. This will block
|
||||||
* if the sink pipe is full
|
* if the sink pipe is full
|
||||||
*
|
*
|
||||||
@@ -798,6 +829,33 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
}
|
}
|
||||||
break;
|
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
|
/* Any unrecognized IOCTL commands will be passed to the contained
|
||||||
* pipe driver.
|
* pipe driver.
|
||||||
*
|
*
|
||||||
@@ -1017,6 +1075,12 @@ int pty_register2(int minor, bool susv1)
|
|||||||
devpair->pp_slave.pd_devpair = devpair;
|
devpair->pp_slave.pd_devpair = devpair;
|
||||||
devpair->pp_slave.pd_oflag = OPOST | ONLCR;
|
devpair->pp_slave.pd_oflag = OPOST | ONLCR;
|
||||||
devpair->pp_slave.pd_lflag = ECHO;
|
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
|
/* Register the master device
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user