Skip to content

Commit

Permalink
drivers/pty: support pty write to kill signal, like serial driver
Browse files Browse the repository at this point in the history
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
  • Loading branch information
Donny9 committed Sep 15, 2024
1 parent 97d6848 commit 4444241
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions drivers/serial/pty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -540,13 +544,24 @@ 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;

inode = filep->f_inode;
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)
Expand Down Expand Up @@ -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_tgkill(-1, pid, SIGINT);
return 1;
}
#endif

#ifdef CONFIG_TTY_SIGTSTP
if (pid > 0 && ch == CONFIG_TTY_SIGTSTP_CHAR)
{
nxsig_tgkill(-1, pid, SIGTSTP);
return 1;
}
#endif

/* Transfer the (possibly translated) character.. This will block
* if the sink pipe is full
*
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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
*
Expand Down

0 comments on commit 4444241

Please sign in to comment.