X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fptyfwd.c;h=d44d70bf9f47046245d0f7230fd9b7a6b8519df4;hp=7225b933ff35a7f3146e13e9a537132311f052f9;hb=8f2665a463ffb2b822c1e3effdb292d2bddf72be;hpb=04d39279245834494baccfdb9349db8bf80abd13 diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c index 7225b933f..d44d70bf9 100644 --- a/src/shared/ptyfwd.c +++ b/src/shared/ptyfwd.c @@ -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;