summaryrefslogtreecommitdiffstats
path: root/login-utils
diff options
context:
space:
mode:
authorKarel Zak2019-03-06 11:54:51 +0100
committerKarel Zak2019-03-06 12:01:18 +0100
commit282ca3d87b4ab2e3f077c959fd5e0f87980120d6 (patch)
treecce5ab6512597f2b9f5eaee112d9e2695f73aeb9 /login-utils
parenttests: add missing ts_check_test_command call (diff)
downloadkernel-qcow2-util-linux-282ca3d87b4ab2e3f077c959fd5e0f87980120d6.tar.gz
kernel-qcow2-util-linux-282ca3d87b4ab2e3f077c959fd5e0f87980120d6.tar.xz
kernel-qcow2-util-linux-282ca3d87b4ab2e3f077c959fd5e0f87980120d6.zip
su: fix --pty terminal initialization
* use proper winsize rather than uninitialized variable (Oops...) * set the current terminal to the raw mode * disable ECHO for non-terminal execution to be compatible with non-pty output Addresses: https://github.com/karelzak/util-linux/issues/767 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils')
-rw-r--r--login-utils/su-common.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
index 0e44eb87c..bf4a47126 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -276,29 +276,26 @@ static void pty_create(struct su_context *su)
if (su->isterm) {
DBG(PTY, ul_debug("create for terminal"));
- struct winsize win;
/* original setting of the current terminal */
if (tcgetattr(STDIN_FILENO, &su->stdin_attrs) != 0)
err(EXIT_FAILURE, _("failed to get terminal attributes"));
-
- /* reuse the current terminal setting for slave */
- slave_attrs = su->stdin_attrs;
- cfmakeraw(&slave_attrs);
-
ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&su->win);
-
/* create master+slave */
- rc = openpty(&su->pty_master, &su->pty_slave, NULL, &slave_attrs, &win);
+ rc = openpty(&su->pty_master, &su->pty_slave, NULL, &su->stdin_attrs, &su->win);
+ /* set the current terminal to raw mode; pty_cleanup() reverses this change on exit */
+ slave_attrs = su->stdin_attrs;
+ cfmakeraw(&slave_attrs);
+ slave_attrs.c_lflag &= ~ECHO;
+ tcsetattr(STDIN_FILENO, TCSANOW, &slave_attrs);
} else {
DBG(PTY, ul_debug("create for non-terminal"));
rc = openpty(&su->pty_master, &su->pty_slave, NULL, NULL, NULL);
- /* set slave attributes */
if (!rc) {
tcgetattr(su->pty_slave, &slave_attrs);
- cfmakeraw(&slave_attrs);
+ slave_attrs.c_lflag &= ~ECHO;
tcsetattr(su->pty_slave, TCSANOW, &slave_attrs);
}
}
@@ -311,12 +308,14 @@ static void pty_create(struct su_context *su)
static void pty_cleanup(struct su_context *su)
{
- if (su->pty_master == -1)
+ struct termios rtt;
+
+ if (su->pty_master == -1 || !su->isterm)
return;
DBG(PTY, ul_debug("cleanup"));
- if (su->isterm)
- tcsetattr(STDIN_FILENO, TCSADRAIN, &su->stdin_attrs);
+ rtt = su->stdin_attrs;
+ tcsetattr(STDIN_FILENO, TCSADRAIN, &rtt);
}
static int write_output(char *obuf, ssize_t bytes)