* 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>
#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;
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,
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;
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");
ts->sigfd = -1;
}
- if (istty)
- lxc_list_del(&ts->node);
-
return ts;
}
SYSWARN("Failed to restore signal mask");
}
- if (isatty(ts->stdinfd))
- lxc_list_del(&ts->node);
-
free(ts);
}
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;
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)
/* 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;
{
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;
{
int ret;
struct lxc_terminal *terminal = &conf->console;
- struct termios oldtios;
if (terminal->path && strcmp(terminal->path, "none") == 0) {
INFO("No terminal requested");
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;
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);
}