summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <LukeShu@sbcglobal.net>2013-11-23 04:57:43 -0500
committerLennart Poettering <lennart@poettering.net>2013-12-11 01:04:21 +0000
commit90d14d2015dda79c7b465b74dd3aaf2dfc25d43c (patch)
treef85d5dd216f2055444169302906ea9c6d896276b
parenteaf73b061604c028aa28f960870a9b46aab2f76a (diff)
ptyfwd: Don't set the output prop of stdin, nor the input props of stdout.
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.
-rw-r--r--src/shared/ptyfwd.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
index 85a0ddc2ec..72aa59efb7 100644
--- a/src/shared/ptyfwd.c
+++ b/src/shared/ptyfwd.c
@@ -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;