]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/terminal.c
Centralize hook names
[mirror_lxc.git] / src / lxc / terminal.c
index 614c07a135bfa7fbd5524e0adaba77d4cb910268..4ea0c5dc3c551d42a9593053445e397a20c31a2c 100644 (file)
@@ -21,7 +21,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
 #include <errno.h>
 #include <fcntl.h>
 #include <lxc/lxccontainer.h>
@@ -42,7 +44,9 @@
 #include "log.h"
 #include "lxclock.h"
 #include "mainloop.h"
+#include "memory_utils.h"
 #include "start.h"
+#include "syscall_wrappers.h"
 #include "terminal.h"
 #include "utils.h"
 
 
 lxc_log_define(terminal, lxc);
 
-static struct lxc_list lxc_ttys;
-
-typedef void (*sighandler_t)(int);
-
-__attribute__((constructor)) void lxc_terminal_init_global(void)
-{
-       lxc_list_init(&lxc_ttys);
-}
-
 void lxc_terminal_winsz(int srcfd, int dstfd)
 {
        int ret;
@@ -92,20 +87,6 @@ void lxc_terminal_winsz(int srcfd, int dstfd)
 static void lxc_terminal_winch(struct lxc_terminal_state *ts)
 {
        lxc_terminal_winsz(ts->stdinfd, ts->masterfd);
-
-       if (ts->winch_proxy)
-               lxc_cmd_terminal_winch(ts->winch_proxy, ts->winch_proxy_lxcpath);
-}
-
-void lxc_terminal_sigwinch(int sig)
-{
-       struct lxc_list *it;
-       struct lxc_terminal_state *ts;
-
-       lxc_list_for_each(it, &lxc_ttys) {
-               ts = it->elem;
-               lxc_terminal_winch(ts);
-       }
 }
 
 int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
@@ -115,7 +96,7 @@ int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
        struct signalfd_siginfo siginfo;
        struct lxc_terminal_state *ts = cbdata;
 
-       ret = read(fd, &siginfo, sizeof(siginfo));
+       ret = lxc_read_nointr(fd, &siginfo, sizeof(siginfo));
        if (ret < 0 || (size_t)ret < sizeof(siginfo)) {
                ERROR("Failed to read signal info");
                return LXC_MAINLOOP_ERROR;
@@ -158,9 +139,6 @@ struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd)
        if (!istty) {
                INFO("fd %d does not refer to a tty device", srcfd);
        } else {
-               /* Add tty to list to be scanned at SIGWINCH time. */
-               lxc_list_add_elem(&ts->node, ts);
-               lxc_list_add_tail(&lxc_ttys, &ts->node);
                ret = sigaddset(&mask, SIGWINCH);
                if (ret < 0)
                        SYSNOTICE("Failed to add SIGWINCH to signal set");
@@ -196,9 +174,6 @@ on_error:
                ts->sigfd = -1;
        }
 
-       if (istty)
-               lxc_list_del(&ts->node);
-
        return ts;
 }
 
@@ -211,9 +186,6 @@ void lxc_terminal_signal_fini(struct lxc_terminal_state *ts)
                        SYSWARN("Failed to restore signal mask");
        }
 
-       if (isatty(ts->stdinfd))
-               lxc_list_del(&ts->node);
-
        free(ts);
 }
 
@@ -228,9 +200,9 @@ static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal)
 
 static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
 {
+       __do_free char *tmp = NULL;
        int ret;
        size_t len;
-       char *tmp;
 
        if (!terminal->log_path || terminal->log_rotate == 0)
                return -EOPNOTSUPP;
@@ -240,7 +212,7 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
                return -EBADF;
 
        len = strlen(terminal->log_path) + sizeof(".1");
-       tmp = alloca(len);
+       tmp = must_realloc(NULL, len);
 
        ret = snprintf(tmp, len, "%s.1", terminal->log_path);
        if (ret < 0 || (size_t)ret >= len)
@@ -570,13 +542,32 @@ static int lxc_terminal_peer_proxy_alloc(struct lxc_terminal *terminal,
        /* This is the proxy terminal that will be given to the client, and
         * that the real terminal master will send to / recv from.
         */
-       ret = openpty(&terminal->proxy.master, &terminal->proxy.slave,
-                     terminal->proxy.name, NULL, NULL);
+       ret = openpty(&terminal->proxy.master, &terminal->proxy.slave, NULL,
+                     NULL, NULL);
        if (ret < 0) {
                SYSERROR("Failed to open proxy terminal");
                return -1;
        }
 
+       ret = ttyname_r(terminal->proxy.slave, terminal->proxy.name,
+                       sizeof(terminal->proxy.name));
+       if (ret < 0) {
+               SYSERROR("Failed to retrieve name of proxy terminal slave");
+               goto on_error;
+       }
+
+       ret = fd_cloexec(terminal->proxy.master, true);
+       if (ret < 0) {
+               SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal master");
+               goto on_error;
+       }
+
+       ret = fd_cloexec(terminal->proxy.slave, true);
+       if (ret < 0) {
+               SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal slave");
+               goto on_error;
+       }
+
        ret = lxc_setup_tios(terminal->proxy.slave, &oldtermio);
        if (ret < 0)
                goto on_error;
@@ -862,19 +853,25 @@ int lxc_terminal_create(struct lxc_terminal *terminal)
 {
        int ret;
 
-       ret = openpty(&terminal->master, &terminal->slave, terminal->name, NULL, NULL);
+       ret = openpty(&terminal->master, &terminal->slave, NULL, NULL, NULL);
        if (ret < 0) {
                SYSERROR("Failed to open terminal");
                return -1;
        }
 
-       ret = fcntl(terminal->master, F_SETFD, FD_CLOEXEC);
+       ret = ttyname_r(terminal->slave, terminal->name, sizeof(terminal->name));
+       if (ret < 0) {
+               SYSERROR("Failed to retrieve name of terminal slave");
+               goto err;
+       }
+
+       ret = fd_cloexec(terminal->master, true);
        if (ret < 0) {
                SYSERROR("Failed to set FD_CLOEXEC flag on terminal master");
                goto err;
        }
 
-       ret = fcntl(terminal->slave, F_SETFD, FD_CLOEXEC);
+       ret = fd_cloexec(terminal->slave, true);
        if (ret < 0) {
                SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave");
                goto err;
@@ -897,7 +894,6 @@ int lxc_terminal_setup(struct lxc_conf *conf)
 {
        int ret;
        struct lxc_terminal *terminal = &conf->console;
-       struct termios oldtios;
 
        if (terminal->path && strcmp(terminal->path, "none") == 0) {
                INFO("No terminal requested");
@@ -908,10 +904,6 @@ int lxc_terminal_setup(struct lxc_conf *conf)
        if (ret < 0)
                return -1;
 
-       ret = lxc_setup_tios(terminal->master, &oldtios);
-       if (ret < 0)
-               return -1;
-
        ret = lxc_terminal_create_log_file(terminal);
        if (ret < 0)
                goto err;
@@ -1042,14 +1034,12 @@ int lxc_console(struct lxc_container *c, int ttynum,
                goto close_fds;
        }
        ts->escape = escape;
-       ts->winch_proxy = c->name;
-       ts->winch_proxy_lxcpath = c->config_path;
        ts->stdoutfd = stdoutfd;
 
        istty = isatty(stdinfd);
        if (istty) {
                lxc_terminal_winsz(stdinfd, masterfd);
-               lxc_cmd_terminal_winch(ts->winch_proxy, ts->winch_proxy_lxcpath);
+               lxc_terminal_winsz(ts->stdinfd, ts->masterfd);
        } else {
                INFO("File descriptor %d does not refer to a terminal", stdinfd);
        }