This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 765f45385ad7d25da6c0b43759f87bc6cdb213d1
Author: Marco Casaroli <[email protected]>
AuthorDate: Thu Oct 29 19:55:29 2026 +0100

    drivers/serial/pty: Set the terminal of the slave also through the master.
    
    TCGETS and TCSETS of a pseudo-terminal read and set the flags of the end
    they are called on.  On other systems the termios of a pty belong to the
    terminal, the slave, also when a program sets them through the master,
    and the master does no echo.
    
    A program that copies the termios of its own terminal (ECHO and ICANON
    set) to the master, and then runs a child on the slave, made the master
    echo every byte that it read from the child back into the input of the
    slave.  When the child did not read its input, that pipe filled, the
    read on the master blocked in the echo, the child blocked on its full
    output pipe, and both waited for each other.
    
    Make TCGETS and TCSETS use the flags of the slave on both ends.  The
    master keeps its own flags, which do no echo.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 drivers/serial/pty.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/serial/pty.c b/drivers/serial/pty.c
index 1a0f096ea0f..009588659f3 100644
--- a/drivers/serial/pty.c
+++ b/drivers/serial/pty.c
@@ -839,11 +839,13 @@ static int pty_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
               break;
             }
 
-          /* And update with flags from this layer */
+          /* The settings of the terminal are the ones of the slave, also
+           * through the master, as on other systems.
+           */
 
-          termiosp->c_iflag = dev->pd_iflag;
-          termiosp->c_oflag = dev->pd_oflag;
-          termiosp->c_lflag = dev->pd_lflag;
+          termiosp->c_iflag = devpair->pp_slave.pd_iflag;
+          termiosp->c_oflag = devpair->pp_slave.pd_oflag;
+          termiosp->c_lflag = devpair->pp_slave.pd_lflag;
 
           /* The special characters that the pair acts on (one set for
            * both ends).  The others are disabled.
@@ -851,10 +853,10 @@ static int pty_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
 
           memset(termiosp->c_cc, _POSIX_VDISABLE, sizeof(termiosp->c_cc));
 #ifdef CONFIG_TTY_SIGINT
-          termiosp->c_cc[VINTR] = dev->pd_devpair->pp_vintr;
+          termiosp->c_cc[VINTR] = devpair->pp_vintr;
 #endif
 #ifdef CONFIG_TTY_SIGTSTP
-          termiosp->c_cc[VSUSP] = dev->pd_devpair->pp_vsusp;
+          termiosp->c_cc[VSUSP] = devpair->pp_vsusp;
 #endif
           termiosp->c_cc[VMIN] = 1;
           ret = OK;
@@ -871,16 +873,18 @@ static int pty_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
               break;
             }
 
-          /* Update the flags we keep at this layer */
+          /* Set the terminal, the slave, also through the master.  The
+           * master keeps its own flags: it never echoes what it reads.
+           */
 
-          dev->pd_iflag = termiosp->c_iflag;
-          dev->pd_oflag = termiosp->c_oflag;
-          dev->pd_lflag = termiosp->c_lflag;
+          devpair->pp_slave.pd_iflag = termiosp->c_iflag;
+          devpair->pp_slave.pd_oflag = termiosp->c_oflag;
+          devpair->pp_slave.pd_lflag = termiosp->c_lflag;
 #ifdef CONFIG_TTY_SIGINT
-          dev->pd_devpair->pp_vintr = termiosp->c_cc[VINTR];
+          devpair->pp_vintr = termiosp->c_cc[VINTR];
 #endif
 #ifdef CONFIG_TTY_SIGTSTP
-          dev->pd_devpair->pp_vsusp = termiosp->c_cc[VSUSP];
+          devpair->pp_vsusp = termiosp->c_cc[VSUSP];
 #endif
           ret = OK;
         }

Reply via email to