lxc/0068-support-record-stdout-stderr-log-of-container-consol.patch
LiFeng c1c967d9bc lxc: make lxc-libs package
Signed-off-by: LiFeng <lifeng68@huawei.com>
2020-02-14 06:13:22 -05:00

1245 lines
40 KiB
Diff

From 25e6f0bfa28a7da88a54da99123e2bbd60da2cb2 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 21 Feb 2019 20:27:47 +0800
Subject: [PATCH 068/139] support record stdout, stderr log of container
console
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/attach.c | 15 +-
src/lxc/attach_options.h | 2 +-
src/lxc/commands.c | 15 +-
src/lxc/commands.h | 2 +-
src/lxc/conf.c | 33 +++--
src/lxc/lxccontainer.c | 79 +++++++---
src/lxc/lxccontainer.h | 35 ++++-
src/lxc/start.c | 67 ++++++++-
src/lxc/start.h | 5 +
src/lxc/terminal.c | 351 ++++++++++++++++++++++++++++++++-------------
src/lxc/terminal.h | 7 +-
src/lxc/tools/arguments.h | 14 +-
src/lxc/tools/lxc_attach.c | 7 +-
src/lxc/tools/lxc_start.c | 22 ++-
14 files changed, 502 insertions(+), 152 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 9768897..c979c85 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -1052,15 +1052,18 @@ static int lxc_attach_terminal(struct lxc_conf *conf,
lxc_terminal_init(terminal);
/* isulad: if we pass fifo in option, use them as init fifos */
- if (options->init_fifo[0] && options->init_fifo[1]) {
- if (terminal->init_fifo[0])
- free(terminal->init_fifo[0]);
+ if (options->init_fifo[0]) {
+ free(terminal->init_fifo[0]);
terminal->init_fifo[0] = strdup(options->init_fifo[0]);
-
- if (terminal->init_fifo[1])
- free(terminal->init_fifo[1]);
+ }
+ if (options->init_fifo[1]) {
+ free(terminal->init_fifo[1]);
terminal->init_fifo[1] = strdup(options->init_fifo[1]);
}
+ if (options->init_fifo[2]) {
+ free(terminal->init_fifo[2]);
+ terminal->init_fifo[2] = strdup(options->init_fifo[2]);
+ }
ret = lxc_terminal_create(terminal);
if (ret < 0) {
diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h
index 7b0a8cb..71c1739 100644
--- a/src/lxc/attach_options.h
+++ b/src/lxc/attach_options.h
@@ -136,7 +136,7 @@ typedef struct lxc_attach_options_t {
/*! File descriptor to log output. */
int log_fd;
- char *init_fifo[2]; /* isulad: default fifos for the start */
+ char *init_fifo[3]; /* isulad: default fifos for the start */
} lxc_attach_options_t;
/*! Default attach options to use */
diff --git a/src/lxc/commands.c b/src/lxc/commands.c
index 46b2805..f0c95df 100644
--- a/src/lxc/commands.c
+++ b/src/lxc/commands.c
@@ -1064,21 +1064,22 @@ reap_client_fd:
*
* Returns 0 when success, else when fail.
*/
-int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo, const char *out_fifo)
+int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo,
+ const char *out_fifo, const char *err_fifo)
{
int ret = 0, stopped = 0;
int len = 0;
char *tmp = NULL;
+ const char *split = "&&&&", *none_fifo_name = "none";
+ const char *cmd_in_fifo = in_fifo ? in_fifo : none_fifo_name;
+ const char *cmd_out_fifo = out_fifo ? out_fifo : none_fifo_name;
+ const char *cmd_err_fifo = err_fifo ? err_fifo : none_fifo_name;
- if (!in_fifo || !out_fifo) {
- return -1;
- }
-
- len = strlen(in_fifo) + strlen("&&&&") + strlen(out_fifo) + 1;
+ len += strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + strlen(split) + strlen(cmd_err_fifo) + 1;
tmp = malloc(len);
if (!tmp)
return -1;
- snprintf(tmp, len, "%s%s%s", in_fifo, "&&&&", out_fifo);
+ snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo);
struct lxc_cmd_rr cmd = {
.req = {
diff --git a/src/lxc/commands.h b/src/lxc/commands.h
index 0c64544..6b64849 100644
--- a/src/lxc/commands.h
+++ b/src/lxc/commands.h
@@ -127,6 +127,6 @@ extern int lxc_cmd_console_log(const char *name, const char *lxcpath,
struct lxc_console_log *log);
extern int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath,
- const char *in_fifo, const char *out_fifo);
+ const char *in_fifo, const char *out_fifo, const char *err_fifo);
#endif /* __commands_h */
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index e139dff..a6b9797 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2067,20 +2067,22 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
return -errno;
}
- ret = fchmod(console->slave, S_IXUSR | S_IXGRP);
- if (ret < 0) {
- SYSERROR("Failed to set mode \"0%o\" to \"%s\"",
- S_IXUSR | S_IXGRP, console->name);
- return -errno;
- }
+ if (console->slave > 0) {
+ ret = fchmod(console->slave, S_IXUSR | S_IXGRP);
+ if (ret < 0) {
+ SYSERROR("Failed to set mode \"0%o\" to \"%s\"",
+ S_IXUSR | S_IXGRP, console->name);
+ return -errno;
+ }
- /* bind mount console->name to '/dev/<ttydir>/console' */
- ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path);
- if (ret < 0) {
- ERROR("Failed to mount \"%s\" on \"%s\"", console->name, lxcpath);
- return -1;
+ /* bind mount console->name to '/dev/<ttydir>/console' */
+ ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path);
+ if (ret < 0) {
+ ERROR("Failed to mount \"%s\" on \"%s\"", console->name, lxcpath);
+ return -1;
+ }
+ DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath);
}
- DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath);
/* bind mount '/dev/<ttydir>/console' to '/dev/console' */
ret = safe_mount(lxcpath, path, "none", MS_BIND, 0, rootfs_path);
@@ -3158,6 +3160,13 @@ struct lxc_conf *lxc_conf_init(void)
/* isulad init console fifos */
new->console.init_fifo[0] = NULL;
new->console.init_fifo[1] = NULL;
+ new->console.init_fifo[2] = NULL;
+ new->console.pipes[0][0] = -1;
+ new->console.pipes[0][1] = -1;
+ new->console.pipes[1][0] = -1;
+ new->console.pipes[1][1] = -1;
+ new->console.pipes[2][0] = -1;
+ new->console.pipes[2][1] = -1;
lxc_list_init(&new->console.fifos);
new->errmsg = NULL;
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 3fd1a66..8a3724c 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -702,6 +702,40 @@ static bool do_lxcapi_want_daemonize(struct lxc_container *c, bool state)
WRAP_API_1(bool, lxcapi_want_daemonize, bool)
+static bool do_lxcapi_want_disable_pty(struct lxc_container *c, bool state)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+
+ if (container_mem_lock(c))
+ return false;
+
+ c->disable_pty = state;
+
+ container_mem_unlock(c);
+
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_want_disable_pty, bool)
+
+static bool do_lxcapi_want_open_stdin(struct lxc_container *c, bool state)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+
+ if (container_mem_lock(c))
+ return false;
+
+ c->open_stdin = state;
+
+ container_mem_unlock(c);
+
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_want_open_stdin, bool)
+
static bool do_lxcapi_want_close_all_fds(struct lxc_container *c, bool state)
{
if (!c || !c->lxc_conf)
@@ -1198,12 +1232,15 @@ reboot:
goto on_error;
}
- if (useinit)
+ if (useinit) {
ret = lxc_execute(c->name, argv, 1, handler, c->config_path,
c->daemonize, &c->error_num, c->start_timeout);
- else
+ } else {
+ handler->disable_pty = c->disable_pty;
+ handler->open_stdin = c->open_stdin;
ret = lxc_start(c->name, argv, handler, c->config_path,
c->daemonize, &c->error_num, c->start_timeout);
+ }
if (conf->reboot == REBOOT_REQ) {
INFO("Container requested reboot");
@@ -5085,11 +5122,11 @@ out:
}
/* isulad add set console fifos*/
-static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out)
+static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out, const char *err)
{
struct lxc_conf *conf;
- if (!c || !c->lxc_conf || !in || !out)
+ if (!c || !c->lxc_conf)
return false;
if (container_mem_lock(c)) {
ERROR("Error getting mem lock");
@@ -5097,19 +5134,27 @@ static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const
}
conf = c->lxc_conf;
- if (conf->console.init_fifo[0])
- free(conf->console.init_fifo[0]);
- conf->console.init_fifo[0] = strdup(in);
-
- if (conf->console.init_fifo[1])
- free(conf->console.init_fifo[1]);
- conf->console.init_fifo[1] = strdup(out);
+ if (in) {
+ if (conf->console.init_fifo[0])
+ free(conf->console.init_fifo[0]);
+ conf->console.init_fifo[0] = strdup(in);
+ }
+ if (out) {
+ if (conf->console.init_fifo[1])
+ free(conf->console.init_fifo[1]);
+ conf->console.init_fifo[1] = strdup(out);
+ }
+ if (err) {
+ if (conf->console.init_fifo[2])
+ free(conf->console.init_fifo[2]);
+ conf->console.init_fifo[2] = strdup(err);
+ }
container_mem_unlock(c);
return true;
}
-WRAP_API_2(bool, lxcapi_set_terminal_default_fifos, const char *, const char *)
+WRAP_API_3(bool, lxcapi_set_terminal_default_fifos, const char *, const char *, const char *)
/* isulad add set info file path */
static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const char *info_file)
@@ -5168,18 +5213,18 @@ static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pi
WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t)
/* isulad add clean resources */
-static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo)
+static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo, const char *err_fifo)
{
bool ret = true;
- if (!c || !c->lxc_conf || !in_fifo || !out_fifo)
+ if (!c || !c->lxc_conf)
return false;
if (container_mem_lock(c)) {
ERROR("Error getting mem lock");
return false;
}
- if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo)) {
+ if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo, err_fifo)) {
ERROR("Error set console fifos");
ret = false;
}
@@ -5188,7 +5233,7 @@ static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_
return ret;
}
-WRAP_API_2(bool, lxcapi_add_terminal_fifo, const char *, const char *)
+WRAP_API_3(bool, lxcapi_add_terminal_fifo, const char *, const char *, const char *)
static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config)
{
@@ -5274,6 +5319,8 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char *
c->init_pid = lxcapi_init_pid;
c->load_config = lxcapi_load_config;
c->want_daemonize = lxcapi_want_daemonize;
+ c->want_disable_pty = lxcapi_want_disable_pty;
+ c->want_open_stdin = lxcapi_want_open_stdin;
c->want_close_all_fds = lxcapi_want_close_all_fds;
c->start = lxcapi_start;
c->startl = lxcapi_startl;
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index c1d83ba..c3368e4 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -137,6 +137,15 @@ struct lxc_container {
/*! Whether container wishes to be daemonized */
bool daemonize;
+ /*! Whether container wishes to create pty or pipes for console log */
+ bool disable_pty;
+
+ /*! Whether container wishes to keep stdin active */
+ bool open_stdin;
+
+ /*! Whether container wishes to detach from container stdio */
+ bool detach;
+
/*! Full path to configuration file */
char *config_path;
@@ -244,6 +253,28 @@ struct lxc_container {
bool (*stop)(struct lxc_container *c);
/*!
+ * \brief Change whether the container wants to create pty or pipes
+ * from the console log.
+ *
+ * \param c Container.
+ * \param state Value for the disable pty bit (0 or 1).
+ *
+ * \return \c true on success, else \c false.
+ */
+ bool (*want_disable_pty)(struct lxc_container *c, bool state);
+
+ /*!
+ * \brief Change whether the container wants to keep stdin active
+ * for parent process of container
+ *
+ * \param c Container.
+ * \param state Value for the open_stdin bit (0 or 1).
+ *
+ * \return \c true on success, else \c false.
+ */
+ bool (*want_open_stdin)(struct lxc_container *c, bool state);
+
+ /*!
* \brief Change whether the container wants to run disconnected
* from the terminal.
*
@@ -875,7 +906,7 @@ struct lxc_container {
*
* \return \c true on success, else \c false.
*/
- bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out);
+ bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out, const char *err);
/*! isulad add
* \brief An API call to add the path of terminal fifos
@@ -885,7 +916,7 @@ struct lxc_container {
*
* \return \c true on success, else \c false.
*/
- bool (*add_terminal_fifos)(struct lxc_container *c, const char *in, const char *out);
+ bool (*add_terminal_fifos)(struct lxc_container *c, const char *in, const char *out, const char *err);
/*! isulad add
* \brief An API call to set the path of info file
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 816b4a2..cad0d76 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -635,6 +635,13 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
}
TRACE("Mainloop is ready");
+ // iSulad: close stdin pipe if we do not want open_stdin with container stdin
+ if (!handler->conf->console.open_stdin) {
+ if (handler->conf->console.pipes[0][1] > 0) {
+ close(handler->conf->console.pipes[0][1]);
+ handler->conf->console.pipes[0][1] = -1;
+ }
+ }
ret = lxc_mainloop(&descr, -1);
close(descr.epfd);
@@ -788,6 +795,8 @@ int lxc_init(const char *name, struct lxc_handler *handler)
int ret;
const char *loglevel;
struct lxc_conf *conf = handler->conf;
+ conf->console.disable_pty = handler->disable_pty;
+ conf->console.open_stdin = handler->open_stdin;
lsm_init();
TRACE("Initialized LSM");
@@ -1244,7 +1253,7 @@ static int do_start(void *data)
* means that migration won't work, but at least we won't spew output
* where it isn't wanted.
*/
- if (handler->daemonize && !handler->conf->autodev) {
+ if (!handler->disable_pty && handler->daemonize && !handler->conf->autodev) {
ret = access(path, F_OK);
if (ret != 0) {
devnull_fd = open_devnull();
@@ -1325,6 +1334,42 @@ static int do_start(void *data)
"privileges");
}
+ /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */
+ if (handler->disable_pty) {
+ if (handler->conf->console.pipes[0][1] >= 0) {
+ close(handler->conf->console.pipes[0][1]);
+ handler->conf->console.pipes[0][1] = -1;
+ }
+
+ if (handler->conf->console.pipes[0][0] >= 0) {
+ ret = dup2(handler->conf->console.pipes[0][0], STDIN_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+
+ if (handler->conf->console.pipes[1][0] >= 0) {
+ close(handler->conf->console.pipes[1][0]);
+ handler->conf->console.pipes[1][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[1][1] >= 0) {
+ ret = dup2(handler->conf->console.pipes[1][1], STDOUT_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+ if (handler->conf->console.pipes[2][0] >= 0) {
+ close(handler->conf->console.pipes[2][0]);
+ handler->conf->console.pipes[2][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[2][1] >= 0) {
+ ret = dup2(handler->conf->console.pipes[2][1], STDERR_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+
+ }
+
/* Some init's such as busybox will set sane tty settings on stdin,
* stdout, stderr which it thinks is the console. We already set them
* the way we wanted on the real terminal, and we want init to do its
@@ -1332,7 +1377,7 @@ static int do_start(void *data)
* make sure that that pty is stdin,stdout,stderr.
*/
setsid();
- if (handler->conf->console.slave >= 0) {
+ if (!handler->disable_pty && handler->conf->console.slave >= 0) {
/* isulad:make the given terminal as controlling terminal to avoid warning
* sh: cannot set terminal process group (-1): Inappropriate ioctl for device
* sh: no job control in this shell */
@@ -1367,7 +1412,7 @@ static int do_start(void *data)
close(handler->sigfd);
- if (handler->conf->console.slave < 0 && handler->daemonize) {
+ if (!handler->disable_pty && handler->conf->console.slave < 0 && handler->daemonize) {
if (devnull_fd < 0) {
devnull_fd = open_devnull();
if (devnull_fd < 0)
@@ -1789,6 +1834,22 @@ static int lxc_spawn(struct lxc_handler *handler)
}
TRACE("Cloned child process %d", handler->pid);
+ /* isulad: close pipe after clone */
+ if (handler->conf->console.pipes[0][0] >= 0) {
+ close(handler->conf->console.pipes[0][0]);
+ handler->conf->console.pipes[0][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[1][1] >= 0) {
+ close(handler->conf->console.pipes[1][1]);
+ handler->conf->console.pipes[1][1] = -1;
+ }
+
+ if (handler->conf->console.pipes[2][1] >= 0) {
+ close(handler->conf->console.pipes[2][1]);
+ handler->conf->console.pipes[2][1] = -1;
+ }
+
/* isulad: save pid/ppid info into file*/
if (handler->conf->container_info_file) {
if (lxc_save_container_info(handler->conf->container_info_file, handler->pid)) {
diff --git a/src/lxc/start.h b/src/lxc/start.h
index ab72e6e..0298991 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -99,6 +99,11 @@ struct lxc_handler {
/* Indicates whether should we close std{in,out,err} on start. */
bool daemonize;
+ /* Indicates whether should we using pipes or pty dup to std{in,out,err} for console log. */
+ bool disable_pty;
+ /* Indicates whether should we keep stdin active. */
+ bool open_stdin;
+
/* The child's pid. */
pid_t pid;
diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c
index 602d43d..dfce92e 100644
--- a/src/lxc/terminal.c
+++ b/src/lxc/terminal.c
@@ -432,7 +432,7 @@ static bool get_now_time_buffer(char *timebuffer, size_t maxsize)
return get_time_buffer(&ts, timebuffer, maxsize);
}
-static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *buf,
+static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf,
int bytes_read)
{
logger_json_file *msg = NULL;
@@ -452,7 +452,7 @@ static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *buf,
}
memcpy(msg->log, buf, bytes_read);
msg->log_len = bytes_read;
- msg->stream = strdup("stdout");
+ msg->stream = type ? strdup(type) : strdup("stdout");
get_now_time_buffer(timebuffer, sizeof(timebuffer));
msg->time = strdup(timebuffer);
@@ -472,7 +472,7 @@ cleanup:
return ret;
}
-static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
+static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char *type, char *buf,
int bytes_read)
{
#define __BUF_CACHE_SIZE (16 * LXC_TERMINAL_BUFFER_SIZE)
@@ -504,7 +504,7 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
// Break up the data that we've buffered up into lines, and log each in turn.
for (index = 0; index < size; index++) {
if (cache[index] == '\n') {
- ret = lxc_logger_write(terminal, cache + begin, index - begin + 1);
+ ret = lxc_logger_write(terminal, type, cache + begin, index - begin + 1);
if (ret < 0) {
WARN("Failed to log msg");
}
@@ -516,7 +516,7 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
* noting that it's a partial log line. */
if (buf == NULL || (begin == 0 && size == __BUF_CACHE_SIZE)) {
if (begin < size) {
- ret = lxc_logger_write(terminal, cache + begin, index - begin + 1);
+ ret = lxc_logger_write(terminal, type, cache + begin, index - begin + 1);
if (ret < 0) {
WARN("Failed to log msg");
}
@@ -541,14 +541,20 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
}
/* isulad: forward data to all fifos */
-static void lxc_forward_data_to_fifo(struct lxc_list *list, char *buf, int r)
+static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, char *buf, int r)
{
struct lxc_list *it,*next;
struct lxc_fifos_fd *elem = NULL;
lxc_list_for_each_safe(it, list, next) {
elem = it->elem;
- lxc_write_nointr(elem->out_fd, buf, r);
+ if (is_err) {
+ if (elem->err_fd >= 0)
+ lxc_write_nointr(elem->err_fd, buf, r);
+ } else {
+ if (elem->out_fd >= 0)
+ lxc_write_nointr(elem->out_fd, buf, r);
+ }
}
return;
@@ -585,7 +591,7 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
terminal->master = -EBADF;
/* write remained buffer to terminal log */
if (terminal->log_fd >= 0) {
- w_log = lxc_terminal_write_log_file(terminal, NULL, 0);
+ w_log = lxc_terminal_write_log_file(terminal, "stdout", NULL, 0);
if (w_log < 0)
TRACE("Failed to write %d bytes to terminal log", r);
}
@@ -601,33 +607,57 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
/* isulad: delete fifos when the client close */
lxc_terminal_delete_fifo(fd, &terminal->fifos);
return LXC_MAINLOOP_CONTINUE;
- } else {
+ } else if (fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) {
+ if (fd == terminal->pipes[1][0]) {
+ w_log = lxc_terminal_write_log_file(terminal, "stdout", NULL, 0);
+ terminal->pipes[1][0] = -EBADF;
+ } else if (fd == terminal->pipes[2][0]) {
+ w_log = lxc_terminal_write_log_file(terminal, "stderr", NULL, 0);
+ terminal->pipes[2][0] = -EBADF;
+ }
+ if (w_log < 0)
+ TRACE("Failed to write %d bytes to terminal log", r);
+ close(fd);
+ return LXC_MAINLOOP_CONTINUE;
+ } else if (fd == terminal->pipes[0][1]) {
+ TRACE("closed stdin pipe of container stdin");
+ terminal->pipes[0][1] = -EBADF;
+ close(fd);
+ return LXC_MAINLOOP_CONTINUE;
+ } else {
ERROR("Handler received unexpected file descriptor");
}
close(fd);
-
return LXC_MAINLOOP_CLOSE;
}
- if (fd == terminal->peer || lxc_terminal_is_fifo(fd, &terminal->fifos))
- w = lxc_write_nointr(terminal->master, buf, r);
+ if (fd == terminal->peer || lxc_terminal_is_fifo(fd, &terminal->fifos)) {
+ if (terminal->master > 0)
+ w = lxc_write_nointr(terminal->master, buf, r);
+ if (terminal->pipes[0][1] > 0)
+ w = lxc_write_nointr(terminal->pipes[0][1], buf, r);
+ }
w_rbuf = w_log = 0;
- if (fd == terminal->master) {
+ if (fd == terminal->master || fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) {
/* write to peer first */
if (terminal->peer >= 0)
w = lxc_write_nointr(terminal->peer, buf, r);
/* isulad: forward data to fifos */
- lxc_forward_data_to_fifo(&terminal->fifos, buf, r);
+ lxc_forward_data_to_fifo(&terminal->fifos, fd == terminal->pipes[2][0], buf, r);
/* write to terminal ringbuffer */
if (terminal->buffer_size > 0)
w_rbuf = lxc_ringbuf_write(&terminal->ringbuf, buf, r);
/* write to terminal log */
- if (terminal->log_fd >= 0)
- w_log = lxc_terminal_write_log_file(terminal, buf, r);
+ if (terminal->log_fd >= 0) {
+ if (fd == terminal->master || fd == terminal->pipes[1][0])
+ w_log = lxc_terminal_write_log_file(terminal, "stdout", buf, r);
+ else if (fd == terminal->pipes[2][0])
+ w_log = lxc_terminal_write_log_file(terminal, "stderr", buf, r);
+ }
}
if (w != r)
@@ -670,6 +700,41 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal)
return 0;
}
+/* isulad add pipes to mainloop */
+static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal)
+{
+ int ret = 0;
+
+ // parent read data from fifo, and send to stdin of container
+ if (terminal->pipes[0][1] > 0) {
+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[0][1],
+ lxc_terminal_io_cb, terminal);
+ if (ret) {
+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[0][1]);
+ return -1;
+ }
+ }
+ // parent read data from stdout of container, and send to fifo
+ if (terminal->pipes[1][0] > 0) {
+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[1][0],
+ lxc_terminal_io_cb, terminal);
+ if (ret) {
+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[1][0]);
+ return -1;
+ }
+ }
+ // parent read data from stderr of container, and send to fifo
+ if (terminal->pipes[2][0] > 0) {
+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[2][0],
+ lxc_terminal_io_cb, terminal);
+ if (ret) {
+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[2][0]);
+ return -1;
+ }
+ }
+ return ret;
+}
+
/* isulad add fifo to mainloop */
static int lxc_terminal_mainloop_add_fifo(struct lxc_terminal *terminal)
{
@@ -696,19 +761,6 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
{
int ret;
- if (terminal->master < 0) {
- INFO("Terminal is not initialized");
- return 0;
- }
-
- ret = lxc_mainloop_add_handler(descr, terminal->master,
- lxc_terminal_io_cb, terminal);
- if (ret < 0) {
- ERROR("Failed to add handler for terminal master fd %d to "
- "mainloop", terminal->master);
- return -1;
- }
-
/* We cache the descr so that we can add an fd to it when someone
* does attach to it in lxc_terminal_allocate().
*/
@@ -720,6 +772,13 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
return -1;
}
+ /* isulad add pipes to mainloop */
+ ret = lxc_terminal_mainloop_add_pipes(terminal);
+ if (ret < 0) {
+ ERROR("Failed to add handler for terminal fifos to mainloop");
+ return -1;
+ }
+
/* isulad add fifo to mainloop */
ret = lxc_terminal_mainloop_add_fifo(terminal);
if (ret < 0) {
@@ -727,6 +786,19 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
return -1;
}
+ if (terminal->master < 0) {
+ INFO("Terminal is not initialized");
+ return 0;
+ }
+
+ ret = lxc_mainloop_add_handler(descr, terminal->master,
+ lxc_terminal_io_cb, terminal);
+ if (ret < 0) {
+ ERROR("Failed to add handler for terminal master fd %d to "
+ "mainloop", terminal->master);
+ return -1;
+ }
+
return 0;
}
@@ -1082,6 +1154,26 @@ void lxc_terminal_delete(struct lxc_terminal *terminal)
close(terminal->log_fd);
terminal->log_fd = -1;
+ /* isulad: close all pipes */
+ if (terminal->pipes[0][0] >= 0)
+ close(terminal->pipes[0][0]);
+ terminal->pipes[0][0] = -1;
+ if (terminal->pipes[0][1] >= 0)
+ close(terminal->pipes[0][1]);
+ terminal->pipes[0][1] = -1;
+ if (terminal->pipes[1][0] >= 0)
+ close(terminal->pipes[1][0]);
+ terminal->pipes[1][0] = -1;
+ if (terminal->pipes[1][1] >= 0)
+ close(terminal->pipes[1][1]);
+ terminal->pipes[1][1] = -1;
+ if (terminal->pipes[2][0] >= 0)
+ close(terminal->pipes[2][0]);
+ terminal->pipes[2][0] = -1;
+ if (terminal->pipes[2][1] >= 0)
+ close(terminal->pipes[2][1]);
+ terminal->pipes[2][1] = -1;
+
/* isulad: delete all fifos */
lxc_terminal_delete_fifo(-1, &terminal->fifos);
}
@@ -1168,59 +1260,79 @@ static int terminal_fifo_open(const char *fifo_path, int flags)
}
/* isulad: set terminal fifos */
-static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, const char *out)
+static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, const char *out, const char *err, int *input_fd)
{
- int fifofd_in = -1, fifofd_out = -1;
+ int fifofd_in = -1, fifofd_out = -1, fifofd_err = -1;
struct lxc_fifos_fd *fifo_elem = NULL;
- if (!in || !out)
+ if ((in && !fifo_exists(in)) || (out && !fifo_exists(out)) || (err && !fifo_exists(err))) {
+ ERROR("File %s or %s or %s does not refer to a FIFO", in, out, err);
return -1;
+ }
- if (!fifo_exists(in) || !fifo_exists(out)) {
- ERROR("File %s or %s does not refer to a FIFO", in, out);
- return -1;
+ if (in) {
+ fifofd_in = terminal_fifo_open(in, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fifofd_in < 0) {
+ SYSERROR("Failed to open FIFO: %s", in);
+ return -1;
+ }
}
- fifofd_in = terminal_fifo_open(in, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
- if (fifofd_in < 0) {
- ERROR("Failed to open FIFO: %s", in);
- return -1;
+ if (out) {
+ fifofd_out = terminal_fifo_open(out, O_WRONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fifofd_out < 0) {
+ SYSERROR("Failed to open FIFO: %s", out);
+ if (fifofd_in >= 0)
+ close(fifofd_in);
+ return -1;
+ }
}
- fifofd_out = terminal_fifo_open(out, O_WRONLY | O_NONBLOCK | O_CLOEXEC);
- if (fifofd_out < 0) {
- ERROR("Failed to open FIFO: %s", out);
- close(fifofd_in);
- return -1;
+ if (err) {
+ fifofd_err = terminal_fifo_open(err, O_WRONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fifofd_err < 0) {
+ SYSERROR("Failed to open FIFO: %s", err);
+ if (fifofd_in >= 0)
+ close(fifofd_in);
+ if (fifofd_out >= 0)
+ close(fifofd_out);
+ return -1;
+ }
}
fifo_elem = malloc(sizeof(*fifo_elem));
if (!fifo_elem) {
- close(fifofd_in);
- close(fifofd_out);
+ if (fifofd_in >= 0)
+ close(fifofd_in);
+ if (fifofd_out >= 0)
+ close(fifofd_out);
+ if (fifofd_err >= 0)
+ close(fifofd_err);
return -1;
}
memset(fifo_elem, 0, sizeof(*fifo_elem));
- fifo_elem->in_fifo = strdup(in);
- fifo_elem->out_fifo = strdup(out);
+ fifo_elem->in_fifo = strdup(in ? in : "");
+ fifo_elem->out_fifo = strdup(out ? out : "");
+ fifo_elem->err_fifo = strdup(err ? err : "");
fifo_elem->in_fd = fifofd_in;
fifo_elem->out_fd = fifofd_out;
+ fifo_elem->err_fd = fifofd_err;
lxc_list_add_elem(&fifo_elem->node, fifo_elem);
lxc_list_add_tail(&console->fifos, &fifo_elem->node);
- return fifofd_in;
+ if (input_fd)
+ *input_fd = fifofd_in;
+
+ return 0;
}
/* isulad: add default fifos */
static int lxc_terminal_fifo_default(struct lxc_terminal *terminal)
{
- if (!terminal->init_fifo[0] || !terminal->init_fifo[1]) {
- DEBUG("Invalid default terminal fifos");
- return 0;
- }
-
- return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1]);
+ if (terminal->init_fifo[0] || terminal->init_fifo[1] || terminal->init_fifo[2])
+ return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1], terminal->init_fifo[2], NULL);
+ return 0;
}
/*
@@ -1245,48 +1357,67 @@ int lxc_terminal_create(struct lxc_terminal *terminal)
{
int ret;
- ret = openpty(&terminal->master, &terminal->slave, NULL, NULL, NULL);
- if (ret < 0) {
- SYSERROR("Failed to open terminal");
- return -1;
- }
+ if (!terminal->disable_pty) {
+ ret = openpty(&terminal->master, &terminal->slave, NULL, NULL, NULL);
+ if (ret < 0) {
+ SYSERROR("Failed to open terminal");
+ return -1;
+ }
- ret = ttyname_r(terminal->slave, terminal->name, sizeof(terminal->name));
- if (ret < 0) {
- SYSERROR("Failed to retrieve name of terminal slave");
- goto err;
- }
+ ret = ttyname_r(terminal->slave, terminal->name, sizeof(terminal->name));
+ if (ret < 0) {
+ SYSERROR("Failed to retrieve name of terminal slave");
+ goto err;
+ }
- /* isulad: clear ONLCR flag */
- ret = use_unix_newline(terminal->master);
- if (ret < 0) {
- SYSERROR("Failed to clear ONLCR flag on terminal master");
- goto err;
- }
+ /* isulad: clear ONLCR flag */
+ ret = use_unix_newline(terminal->master);
+ if (ret < 0) {
+ SYSERROR("Failed to clear ONLCR flag on terminal master");
+ goto err;
+ }
- ret = fd_cloexec(terminal->master, true);
- if (ret < 0) {
- SYSERROR("Failed to set FD_CLOEXEC flag on terminal master");
- goto err;
- }
+ ret = fd_cloexec(terminal->master, true);
+ if (ret < 0) {
+ SYSERROR("Failed to set FD_CLOEXEC flag on terminal master");
+ goto err;
+ }
- /* isulad: make master NONBLOCK */
- ret = fd_nonblock(terminal->master);
- if (ret < 0) {
- SYSERROR("Failed to set O_NONBLOCK flag on terminal master");
- goto err;
- }
+ /* isulad: make master NONBLOCK */
+ ret = fd_nonblock(terminal->master);
+ if (ret < 0) {
+ SYSERROR("Failed to set O_NONBLOCK flag on terminal master");
+ goto err;
+ }
- ret = fd_cloexec(terminal->slave, true);
- if (ret < 0) {
- SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave");
- goto err;
- }
+ ret = fd_cloexec(terminal->slave, true);
+ if (ret < 0) {
+ SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave");
+ goto err;
+ }
- ret = lxc_terminal_peer_default(terminal);
- if (ret < 0) {
- ERROR("Failed to allocate proxy terminal");
- goto err;
+ ret = lxc_terminal_peer_default(terminal);
+ if (ret < 0) {
+ ERROR("Failed to allocate proxy terminal");
+ goto err;
+ }
+ } else {
+ /* isulad: create 3 pipes */
+ /* for stdin */
+ if (pipe2(terminal->pipes[0], O_CLOEXEC)) {
+ ERROR("Failed to create stdin pipe");
+ goto err;
+ }
+ /* for stdout */
+ if (pipe2(terminal->pipes[1], O_NONBLOCK | O_CLOEXEC)) {
+ ERROR("Failed to create stdout pipe");
+ goto err;
+ }
+ /* for stderr */
+ if (pipe2(terminal->pipes[2], O_NONBLOCK | O_CLOEXEC)) {
+ ERROR("Failed to create stderr pipe");
+ goto err;
+ }
}
/* isulad: open fifos */
@@ -1581,6 +1712,13 @@ void lxc_terminal_init(struct lxc_terminal *terminal)
/* isulad init console fifos */
terminal->init_fifo[0] = NULL;
terminal->init_fifo[1] = NULL;
+ terminal->init_fifo[2] = NULL;
+ terminal->pipes[0][0] = -1;
+ terminal->pipes[0][1] = -1;
+ terminal->pipes[1][0] = -1;
+ terminal->pipes[1][1] = -1;
+ terminal->pipes[2][0] = -1;
+ terminal->pipes[2][1] = -1;
lxc_list_init(&terminal->fifos);
}
@@ -1599,8 +1737,14 @@ int lxc_terminal_delete_fifo(int fd, struct lxc_list *list)
free(elem->in_fifo);
if (elem->out_fifo)
free(elem->out_fifo);
- close(elem->in_fd);
- close(elem->out_fd);
+ if (elem->err_fifo)
+ free(elem->err_fifo);
+ if (elem->in_fd >= 0)
+ close(elem->in_fd);
+ if (elem->out_fd >= 0)
+ close(elem->out_fd);
+ if (elem->err_fd >= 0)
+ close(elem->err_fd);
free(elem);
}
}
@@ -1617,6 +1761,7 @@ void lxc_terminal_conf_free(struct lxc_terminal *terminal)
/*isulad: free console fifos */
free(terminal->init_fifo[0]);
free(terminal->init_fifo[1]);
+ free(terminal->init_fifo[2]);
lxc_terminal_delete_fifo(-1, &terminal->fifos);
}
@@ -1647,7 +1792,8 @@ int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames)
int ret = 0;
struct lxc_terminal *terminal = &conf->console;
int fifofd_in = -1;
- char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL;
+ char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL, *err = NULL;
+ const char *none_fifo_name = "none";
tmp = strdup(fifonames);
if (!tmp) {
@@ -1660,14 +1806,27 @@ int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames)
ret = -1;
goto free_out;
}
+ if (strcmp(in, none_fifo_name) == 0)
+ in = NULL;
+
out = strtok_r(NULL, "&&&&", &saveptr);
if (!out) {
ret = -1;
goto free_out;
}
+ if (strcmp(out, none_fifo_name) == 0)
+ out = NULL;
- fifofd_in = lxc_terminal_set_fifo(terminal, in, out);
- if (fifofd_in < 0) {
+ err = strtok_r(NULL, "&&&&", &saveptr);
+ if (!err) {
+ ret = -1;
+ goto free_out;
+ }
+ if (strcmp(err, none_fifo_name) == 0)
+ err = NULL;
+
+ ret = lxc_terminal_set_fifo(terminal, in, out, err, &fifofd_in);
+ if (ret < 0) {
ERROR("Faild to set fifos to console config");
ret = -1;
goto free_out;
diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h
index 0c9653c..9bb341f 100644
--- a/src/lxc/terminal.h
+++ b/src/lxc/terminal.h
@@ -115,16 +115,21 @@ struct lxc_terminal {
/* the in-memory ringbuffer */
struct lxc_ringbuf ringbuf;
};
- char *init_fifo[2]; /* isulad: default fifos for the start */
+ char *init_fifo[3]; /* isulad: default fifos for the start */
struct lxc_list fifos; /* isulad: fifos used to forward teminal */
+ bool disable_pty;
+ bool open_stdin;
+ int pipes[3][2]; /* isulad: pipes for dup to container fds of stdin,stdout,stderr on daemonize mode*/
};
/* isulad: fifo struct */
struct lxc_fifos_fd {
char *in_fifo;
char *out_fifo;
+ char *err_fifo;
int in_fd;
int out_fd;
+ int err_fd;
struct lxc_list node;
};
diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h
index afab9f5..d03f8a4 100644
--- a/src/lxc/tools/arguments.h
+++ b/src/lxc/tools/arguments.h
@@ -51,6 +51,8 @@ struct lxc_arguments {
char *log_priority;
int quiet;
int daemonize;
+ int disable_pty;
+ int open_stdin;
const char *rcfile;
const char *console;
const char *console_log;
@@ -62,7 +64,7 @@ struct lxc_arguments {
/* for lxc-start */
const char *share_ns[32]; /* size must be greater than LXC_NS_MAX */
- char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */
+ char *terminal_fifos[3]; /* isulad add, fifos used to redirct stdin/out/err */
const char *container_info; /* isulad: file used to store pid and ppid info of container */
const char *exit_monitor_fifo; /* isulad: fifo used to monitor state of monitor process */
unsigned int start_timeout; /* isulad: Seconds for waiting on a container to start before it is killed*/
@@ -179,9 +181,13 @@ struct lxc_arguments {
/* isulad add begin */
#define OPT_INPUT_FIFO OPT_USAGE - 7
#define OPT_OUTPUT_FIFO OPT_USAGE - 8
-#define OPT_CONTAINER_INFO OPT_USAGE - 9
-#define OPT_EXIT_FIFO OPT_USAGE - 10
-#define OPT_START_TIMEOUT OPT_USAGE - 11
+#define OPT_STDERR_FIFO OPT_USAGE - 9
+#define OPT_CONTAINER_INFO OPT_USAGE - 10
+#define OPT_EXIT_FIFO OPT_USAGE - 11
+#define OPT_START_TIMEOUT OPT_USAGE - 12
+#define OPT_DISABLE_PTY OPT_USAGE - 13
+#define OPT_OPEN_STDIN OPT_USAGE - 14
+
/* isulad add end*/
extern int lxc_arguments_parse(struct lxc_arguments *args, int argc,
diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c
index acdf8a0..674050d 100644
--- a/src/lxc/tools/lxc_attach.c
+++ b/src/lxc/tools/lxc_attach.c
@@ -77,6 +77,7 @@ static const struct option my_longopts[] = {
{"rcfile", required_argument, 0, 'f'},
{"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, /* isulad add terminal fifos*/
{"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO},
+ {"err-fifo", required_argument, 0, OPT_STDERR_FIFO},
LXC_COMMON_OPTIONS
};
@@ -201,6 +202,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
case OPT_OUTPUT_FIFO:
args->terminal_fifos[1] = arg;
break;
+ case OPT_STDERR_FIFO:
+ args->terminal_fifos[2] = arg;
+ break;
}
return 0;
@@ -460,9 +464,10 @@ int main(int argc, char *argv[])
if (elevated_privileges)
attach_options.attach_flags &= ~(elevated_privileges);
- if (my_args.terminal_fifos[0] && my_args.terminal_fifos[1]) {
+ if (my_args.terminal_fifos[0] || my_args.terminal_fifos[1] || my_args.terminal_fifos[2]) {
attach_options.init_fifo[0] = my_args.terminal_fifos[0];
attach_options.init_fifo[1] = my_args.terminal_fifos[1];
+ attach_options.init_fifo[2] = my_args.terminal_fifos[2];
attach_options.attach_flags |= LXC_ATTACH_TERMINAL;
} else if (stdfd_is_pty()) {
attach_options.attach_flags |= LXC_ATTACH_TERMINAL;
diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c
index ec48701..183fafc 100644
--- a/src/lxc/tools/lxc_start.c
+++ b/src/lxc/tools/lxc_start.c
@@ -73,9 +73,12 @@ static const struct option my_longopts[] = {
/* isulad add begin */
{"in-fifo", required_argument, 0, OPT_INPUT_FIFO},
{"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO},
+ {"err-fifo", required_argument, 0, OPT_STDERR_FIFO},
{"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO},
{"exit-fifo", required_argument, 0, OPT_EXIT_FIFO},
{"start-timeout", required_argument, 0, OPT_START_TIMEOUT},
+ {"disable-pty", no_argument, 0, OPT_DISABLE_PTY},
+ {"open-stdin", no_argument, 0, OPT_OPEN_STDIN},
/* isulad add end */
LXC_COMMON_OPTIONS
};
@@ -166,6 +169,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
case OPT_OUTPUT_FIFO:
args->terminal_fifos[1] = arg;
break;
+ case OPT_STDERR_FIFO:
+ args->terminal_fifos[2] = arg;
+ break;
case OPT_CONTAINER_INFO:
args->container_info = arg;
break;
@@ -179,6 +185,12 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
}
args->start_timeout = (unsigned int)atoi(arg);
break;
+ case OPT_DISABLE_PTY:
+ args->disable_pty = 1;
+ break;
+ case OPT_OPEN_STDIN:
+ args->open_stdin = 1;
+ break;
}
return 0;
}
@@ -381,11 +393,17 @@ int main(int argc, char *argv[])
if (!my_args.daemonize)
c->want_daemonize(c, false);
+ if (my_args.disable_pty)
+ c->want_disable_pty(c, true);
+
+ if (my_args.open_stdin)
+ c->want_open_stdin(c, true);
+
if (my_args.close_all_fds)
c->want_close_all_fds(c, true);
- if (my_args.terminal_fifos[0] && my_args.terminal_fifos[1])
- c->set_terminal_init_fifos(c, my_args.terminal_fifos[0], my_args.terminal_fifos[1]);
+ if (my_args.terminal_fifos[0] || my_args.terminal_fifos[1] || my_args.terminal_fifos[2])
+ c->set_terminal_init_fifos(c, my_args.terminal_fifos[0], my_args.terminal_fifos[1], my_args.terminal_fifos[2]);
if (args == default_args)
err = c->start(c, 0, NULL) ? EXIT_SUCCESS : EXIT_FAILURE;
--
1.8.3.1