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>
This commit is contained in:
parent
2648be66d2
commit
282ca3d87b
|
@ -276,29 +276,26 @@ static void pty_create(struct su_context *su)
|
||||||
|
|
||||||
if (su->isterm) {
|
if (su->isterm) {
|
||||||
DBG(PTY, ul_debug("create for terminal"));
|
DBG(PTY, ul_debug("create for terminal"));
|
||||||
struct winsize win;
|
|
||||||
|
|
||||||
/* original setting of the current terminal */
|
/* original setting of the current terminal */
|
||||||
if (tcgetattr(STDIN_FILENO, &su->stdin_attrs) != 0)
|
if (tcgetattr(STDIN_FILENO, &su->stdin_attrs) != 0)
|
||||||
err(EXIT_FAILURE, _("failed to get terminal attributes"));
|
err(EXIT_FAILURE, _("failed to get terminal attributes"));
|
||||||
|
ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&su->win);
|
||||||
|
/* create master+slave */
|
||||||
|
rc = openpty(&su->pty_master, &su->pty_slave, NULL, &su->stdin_attrs, &su->win);
|
||||||
|
|
||||||
/* reuse the current terminal setting for slave */
|
/* set the current terminal to raw mode; pty_cleanup() reverses this change on exit */
|
||||||
slave_attrs = su->stdin_attrs;
|
slave_attrs = su->stdin_attrs;
|
||||||
cfmakeraw(&slave_attrs);
|
cfmakeraw(&slave_attrs);
|
||||||
|
slave_attrs.c_lflag &= ~ECHO;
|
||||||
ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&su->win);
|
tcsetattr(STDIN_FILENO, TCSANOW, &slave_attrs);
|
||||||
|
|
||||||
/* create master+slave */
|
|
||||||
rc = openpty(&su->pty_master, &su->pty_slave, NULL, &slave_attrs, &win);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DBG(PTY, ul_debug("create for non-terminal"));
|
DBG(PTY, ul_debug("create for non-terminal"));
|
||||||
rc = openpty(&su->pty_master, &su->pty_slave, NULL, NULL, NULL);
|
rc = openpty(&su->pty_master, &su->pty_slave, NULL, NULL, NULL);
|
||||||
|
|
||||||
/* set slave attributes */
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
tcgetattr(su->pty_slave, &slave_attrs);
|
tcgetattr(su->pty_slave, &slave_attrs);
|
||||||
cfmakeraw(&slave_attrs);
|
slave_attrs.c_lflag &= ~ECHO;
|
||||||
tcsetattr(su->pty_slave, TCSANOW, &slave_attrs);
|
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)
|
static void pty_cleanup(struct su_context *su)
|
||||||
{
|
{
|
||||||
if (su->pty_master == -1)
|
struct termios rtt;
|
||||||
|
|
||||||
|
if (su->pty_master == -1 || !su->isterm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DBG(PTY, ul_debug("cleanup"));
|
DBG(PTY, ul_debug("cleanup"));
|
||||||
if (su->isterm)
|
rtt = su->stdin_attrs;
|
||||||
tcsetattr(STDIN_FILENO, TCSADRAIN, &su->stdin_attrs);
|
tcsetattr(STDIN_FILENO, TCSADRAIN, &rtt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_output(char *obuf, ssize_t bytes)
|
static int write_output(char *obuf, ssize_t bytes)
|
||||||
|
|
Loading…
Reference in New Issue