chiark / gitweb /
ptyfwd: Don't set the output prop of stdin, nor the input props of stdout.
authorLuke Shumaker <LukeShu@sbcglobal.net>
Sat, 23 Nov 2013 09:57:43 +0000 (04:57 -0500)
committerLennart Poettering <lennart@poettering.net>
Wed, 11 Dec 2013 01:04:21 +0000 (01:04 +0000)
It was calling cfmakeraw(3) on the properties for STDIN_FILENO; cfmakeraw
sets both input and output properties.  If (and only if) stdin and stdout
are the same device is this correct.  Otherwise, we must change only the
input properties of stdin, and only the output properties of stdout.

src/shared/ptyfwd.c

index 85a0ddc2ecbe3b866b2913e09909b0293da60533..72aa59efb7e30be87ce82e8accd8470cae6a20a2 100644 (file)
@@ -341,29 +341,40 @@ static int process_pty_loop(int master, sigset_t *mask, pid_t kill_pid, int sign
 }
 
 int process_pty(int master, sigset_t *mask, pid_t kill_pid, int signo) {
-        struct termios saved_attr;
-        bool saved = false;
+        struct termios saved_stdin_attr, raw_stdin_attr;
+        struct termios saved_stdout_attr, raw_stdout_attr;
+        bool saved_stdin = false;
+        bool saved_stdout = false;
         struct winsize ws;
         int r;
 
         if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
                 ioctl(master, TIOCSWINSZ, &ws);
 
-        if (tcgetattr(STDIN_FILENO, &saved_attr) >= 0) {
-                struct termios raw_attr;
-                saved = true;
+        if (tcgetattr(STDIN_FILENO, &saved_stdin_attr) >= 0) {
+                saved_stdin = true;
 
-                raw_attr = saved_attr;
-                cfmakeraw(&raw_attr);
-                raw_attr.c_lflag &= ~ECHO;
-
-                tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr);
+                raw_stdin_attr = saved_stdin_attr;
+                cfmakeraw(&raw_stdin_attr);
+                raw_stdin_attr.c_oflag = saved_stdin_attr.c_oflag;
+                tcsetattr(STDIN_FILENO, TCSANOW, &raw_stdin_attr);
+        }
+        if (tcgetattr(STDOUT_FILENO, &saved_stdout_attr) >= 0) {
+                saved_stdout = true;
+
+                raw_stdout_attr = saved_stdout_attr;
+                cfmakeraw(&raw_stdout_attr);
+                raw_stdout_attr.c_iflag = saved_stdout_attr.c_iflag;
+                raw_stdout_attr.c_lflag = saved_stdout_attr.c_lflag;
+                tcsetattr(STDOUT_FILENO, TCSANOW, &raw_stdout_attr);
         }
 
         r = process_pty_loop(master, mask, kill_pid, signo);
 
-        if (saved)
-                tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
+        if (saved_stdout)
+                tcsetattr(STDOUT_FILENO, TCSANOW, &saved_stdout_attr);
+        if (saved_stdin)
+                tcsetattr(STDIN_FILENO, TCSANOW, &saved_stdin_attr);
 
         return r;