The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/848
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Scenario: - lxc-attach to container with pty allocated inside of the container. - shutdown container lxc-attach did not reset the terminal attributes to oldtios which caused various problems and users had to call /usr/bin/reset. This patch ensures that lxc-attach resets oldtios even in such cases. Additionally, this commit makes the exit code in main() cleaner and most of all, correct. Before we called lxc_container_put() before waitpid(). Let's do it the other way around! Signed-off-by: Christian Brauner <christian.brau...@mailbox.org>
From f7bb32fc80b2de5837957a1f7aeac2982019feec Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@mailbox.org> Date: Thu, 25 Feb 2016 11:57:11 +0100 Subject: [PATCH] lxc-attach: ensure that oldtios is set Scenario: - lxc-attach to container with pty allocated inside of the container. - shutdown container lxc-attach did not reset the terminal attributes to oldtios which caused various problems and users had to call /usr/bin/reset. This patch ensures that lxc-attach resets oldtios even in such cases. Additionally, this commit makes the exit code in main() cleaner and most of all, correct. Before we called lxc_container_put() before waitpid(). Let's do it the other way around! Signed-off-by: Christian Brauner <christian.brau...@mailbox.org> --- src/lxc/lxc_attach.c | 65 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c index 3439b2f..fcccb72 100644 --- a/src/lxc/lxc_attach.c +++ b/src/lxc/lxc_attach.c @@ -207,6 +207,7 @@ struct wrapargs { lxc_attach_command_t *command; struct lxc_tty_state *ts; struct lxc_console *console; + struct termios *oldtios; int ptyfd; }; @@ -286,16 +287,22 @@ static int pty_in_container(void *p) return -1; } - /* Get termios from one of the stdfds. */ - struct termios oldtios; - ret = lxc_setup_tios(args->ptyfd, &oldtios); - if (ret < 0) + args->oldtios->c_iflag &= ~IGNBRK; + args->oldtios->c_iflag &= BRKINT; + args->oldtios->c_lflag &= ~(ECHO | ICANON | ISIG); + args->oldtios->c_cc[VMIN] = 1; + args->oldtios->c_cc[VTIME] = 0; + + /* Set new termios. */ + if (tcsetattr(args->ptyfd, TCSAFLUSH, args->oldtios)) { + ERROR("failed to set new terminal settings"); return -1; + } /* Create master/slave fd pair for pty. */ pid = fork_pty(&master); if (pid < 0) - goto err1; + return -1; /* Pass windowsize from one of the stdfds to the current masterfd. */ lxc_console_winsz(args->ptyfd, master); @@ -317,7 +324,7 @@ static int pty_in_container(void *p) args->ts = lxc_console_sigwinch_init(args->ptyfd, master); if (!args->ts) { ret = -1; - goto err2; + goto err1; } args->ts->escape = -1; args->ts->stdoutfd = STDOUT_FILENO; @@ -327,7 +334,7 @@ static int pty_in_container(void *p) ret = lxc_mainloop_open(&descr); if (ret) { ERROR("failed to create mainloop"); - goto err3; + goto err2; } /* Register sigwinch handler in mainloop. */ @@ -335,7 +342,7 @@ static int pty_in_container(void *p) lxc_console_cb_sigwinch_fd, args->ts); if (ret) { ERROR("failed to add handler for SIGWINCH fd"); - goto err4; + goto err3; } /* Register i/o callbacks in mainloop. */ @@ -343,30 +350,28 @@ static int pty_in_container(void *p) lxc_console_cb_tty_stdin, args->ts); if (ret) { ERROR("failed to add handler for stdinfd"); - goto err4; + goto err3; } ret = lxc_mainloop_add_handler(&descr, args->ts->masterfd, lxc_console_cb_tty_master, args->ts); if (ret) { ERROR("failed to add handler for masterfd"); - goto err4; + goto err3; } ret = lxc_mainloop(&descr, -1); if (ret) { ERROR("mainloop returned an error"); - goto err4; + goto err3; } -err4: - lxc_mainloop_close(&descr); err3: - lxc_console_sigwinch_fini(args->ts); + lxc_mainloop_close(&descr); err2: - close(args->ts->masterfd); + lxc_console_sigwinch_fini(args->ts); err1: - tcsetattr(args->ptyfd, TCSAFLUSH, &oldtios); + close(args->ts->masterfd); ret = lxc_wait_for_pid_status(pid); if (ret < 0) @@ -537,6 +542,7 @@ int main(int argc, char *argv[]) wrap.command->argv = (char**)my_args.argv; } + struct termios oldtios; if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO)) { if (isatty(STDIN_FILENO)) wrap.ptyfd = STDIN_FILENO; @@ -544,9 +550,19 @@ int main(int argc, char *argv[]) wrap.ptyfd = STDOUT_FILENO; else if (isatty(STDERR_FILENO)) wrap.ptyfd = STDERR_FILENO; + + /* Get current termios */ + if (tcgetattr(wrap.ptyfd, &oldtios)) + SYSERROR("failed to get current terminal settings"); + wrap.oldtios = &oldtios; + + /* Try to allocate pty in the container. */ ret = c->attach(c, pty_in_container, &wrap, &attach_options, &pid); - if (ret < 0) + if (ret < 0) { + wrap.oldtios = NULL; + /* Try to allocate pty on the host. */ ret = pty_on_host(c, &wrap, &pid); + } } else { if (my_args.argc > 1) ret = c->attach(c, lxc_attach_run_command, &command, &attach_options, &pid); @@ -554,17 +570,22 @@ int main(int argc, char *argv[]) ret = c->attach(c, lxc_attach_run_shell, NULL, &attach_options, &pid); } - lxc_container_put(c); - if (ret < 0) - exit(EXIT_FAILURE); + goto out; ret = lxc_wait_for_pid_status(pid); if (ret < 0) - exit(EXIT_FAILURE); + goto out; if (WIFEXITED(ret)) - return WEXITSTATUS(ret); + ret = WEXITSTATUS(ret); + +out: + if (wrap.oldtios) + tcsetattr(wrap.ptyfd, TCSAFLUSH, &oldtios); + lxc_container_put(c); + if (ret >= 0) + exit(ret); exit(EXIT_FAILURE); }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel