chiark / gitweb /
conf-parser: minor optimization in config_parse_string()
[elogind.git] / src / shared / ptyfwd.c
index 7225b933ff35a7f3146e13e9a537132311f052f9..d44d70bf9f47046245d0f7230fd9b7a6b8519df4 100644 (file)
@@ -78,9 +78,9 @@ static int process_pty_loop(int master, sigset_t *mask, pid_t kill_pid, int sign
         assert(kill_pid == 0 || kill_pid > 1);
         assert(signo >= 0 && signo < _NSIG);
 
-        fd_nonblock(STDIN_FILENO, 1);
-        fd_nonblock(STDOUT_FILENO, 1);
-        fd_nonblock(master, 1);
+        fd_nonblock(STDIN_FILENO, true);
+        fd_nonblock(STDOUT_FILENO, true);
+        fd_nonblock(master, true);
 
         signal_fd = signalfd(-1, mask, SFD_NONBLOCK|SFD_CLOEXEC);
         if (signal_fd < 0) {
@@ -305,7 +305,7 @@ static int process_pty_loop(int master, sigset_t *mask, pid_t kill_pid, int sign
                                         struct winsize ws;
 
                                         /* The window size changed, let's forward that. */
-                                        if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
+                                        if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
                                                 ioctl(master, TIOCSWINSZ, &ws);
 
                                 } else if (sfsi.ssi_signo == SIGTERM && kill_pid > 0 && signo > 0 && !tried_orderly_shutdown) {
@@ -341,29 +341,45 @@ 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(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
+        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);
+
+        /* STDIN/STDOUT should not be nonblocking normally, so let's
+         * unconditionally reset it */
+        fd_nonblock(STDIN_FILENO, false);
+        fd_nonblock(STDOUT_FILENO, false);
 
         return r;