}
/* Build a space-separate list of ptys to pass to systemd. */
-static bool append_ptyname(char **pp, char *name)
+static bool append_ttyname(char **pp, char *name)
{
char *p;
{
int i, ret;
const struct lxc_tty_info *ttys = &conf->ttys;
- char *ttydir = conf->ttydir;
+ char *ttydir = ttys->dir;
char path[MAXPATHLEN], lxcpath[MAXPATHLEN];
if (!conf->rootfs.path)
return 0;
- for (i = 0; i < ttys->nbtty; i++) {
+ for (i = 0; i < ttys->max; i++) {
struct lxc_terminal_info *tty = &ttys->tty[i];
ret = snprintf(path, sizeof(path), "/dev/tty%d", i + 1);
path);
}
- if (!append_ptyname(&conf->pty_names, tty->name)) {
+ if (!append_ttyname(&conf->ttys.tty_names, tty->name)) {
ERROR("Error setting up container_ttys string");
return -1;
}
}
- INFO("Finished setting up %d /dev/tty<N> device(s)", ttys->nbtty);
+ INFO("Finished setting up %zu /dev/tty<N> device(s)", ttys->max);
return 0;
}
struct lxc_tty_info *ttys = &conf->ttys;
/* no tty in the configuration */
- if (!conf->tty)
+ if (ttys->max == 0)
return 0;
- ttys->tty = malloc(sizeof(*ttys->tty) * conf->tty);
+ ttys->tty = malloc(sizeof(*ttys->tty) * ttys->max);
if (!ttys->tty)
return -ENOMEM;
- for (i = 0; i < conf->tty; i++) {
+ for (i = 0; i < ttys->max; i++) {
struct lxc_terminal_info *tty = &ttys->tty[i];
ret = openpty(&tty->master, &tty->slave,
tty->name, NULL, NULL);
if (ret) {
SYSERROR("Failed to create tty %d", i);
- ttys->nbtty = i;
+ ttys->max = i;
lxc_delete_tty(ttys);
return -ENOTTY;
}
tty->busy = 0;
}
- ttys->nbtty = conf->tty;
-
- INFO("Finished creating %d tty devices", conf->tty);
+ INFO("Finished creating %zu tty devices", ttys->max);
return 0;
}
{
int i;
- for (i = 0; i < ttys->nbtty; i++) {
+ for (i = 0; i < ttys->max; i++) {
struct lxc_terminal_info *tty = &ttys->tty[i];
close(tty->master);
free(ttys->tty);
ttys->tty = NULL;
- ttys->nbtty = 0;
}
static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
struct lxc_tty_info *ttys = &conf->ttys;
int sock = handler->data_sock[0];
- if (conf->tty == 0)
+ if (ttys->max == 0)
return 0;
- for (i = 0; i < conf->tty; i++) {
+ for (i = 0; i < ttys->max; i++) {
int ttyfds[2];
struct lxc_terminal_info *tty = &ttys->tty[i];
}
if (ret < 0)
- ERROR("Failed to send %d ttys to parent: %s", conf->tty,
+ ERROR("Failed to send %zu ttys to parent: %s", ttys->max,
strerror(errno));
else
- TRACE("Sent %d ttys to parent", conf->tty);
+ TRACE("Sent %zu ttys to parent", ttys->max);
return ret;
}
}
}
- if (conf->pty_names) {
- ret = setenv("container_ttys", conf->pty_names, 1);
+ if (conf->ttys.tty_names) {
+ ret = setenv("container_ttys", conf->ttys.tty_names, 1);
if (ret < 0)
- SYSERROR("Failed to set \"container_ttys=%s\"", conf->pty_names);
+ SYSERROR("Failed to set \"container_ttys=%s\"", conf->ttys.tty_names);
}
ret = 0;
}
ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console,
- lxc_conf->ttydir);
+ lxc_conf->ttys.dir);
if (ret < 0) {
ERROR("Failed to setup console");
return -1;
if (conf->logfd != -1)
close(conf->logfd);
free(conf->utsname);
- free(conf->ttydir);
+ free(conf->ttys.dir);
+ free(conf->ttys.tty_names);
free(conf->fstab);
free(conf->rcfile);
free(conf->execute_cmd);
free(conf->init_cmd);
free(conf->init_cwd);
free(conf->unexpanded_config);
- free(conf->pty_names);
free(conf->syslog);
lxc_free_networks(&conf->network);
free(conf->lsm_aa_profile);
/* Defines the number of tty configured and contains the
* instantiated ptys
- * @nbtty = number of configured ttys
+ * @max = number of configured ttys
*/
struct lxc_tty_info {
- int nbtty;
+ size_t max;
+ char *dir;
+ char *tty_names;
struct lxc_terminal_info *tty;
};
struct lxc_conf {
/* Pointer to the name of the container. Do not free! */
const char *name;
- unsigned int tty;
- unsigned int pts;
bool is_execute;
int reboot;
signed long personality;
struct lxc_list caps;
struct lxc_list keepcaps;
- struct lxc_tty_info ttys;
+
/* Comma-separated list of lxc.tty.max pty names. */
- char *pty_names;
+ struct lxc_tty_info ttys;
+
+ unsigned int pts;
struct lxc_terminal console;
struct lxc_rootfs rootfs;
- char *ttydir;
bool close_all_fds;
struct {
static int set_config_tty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
+ int ret;
+ unsigned int nbtty = 0;
+
if (lxc_config_value_empty(value)) {
- lxc_conf->tty = 0;
+ lxc_conf->ttys.max = 0;
return 0;
}
- return lxc_safe_uint(value, &lxc_conf->tty);
+ ret = lxc_safe_uint(value, &nbtty);
+ if (ret < 0)
+ return -1;
+
+ lxc_conf->ttys.max = nbtty;
+ return 0;
}
static int set_config_tty_dir(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- return set_config_string_item_max(&lxc_conf->ttydir, value,
+ return set_config_string_item_max(&lxc_conf->ttys.dir, value,
NAME_MAX + 1);
}
static int get_config_tty_max(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_int(c, retv, inlen, c->tty);
+ return lxc_get_conf_size_t(c, retv, inlen, c->ttys.max);
}
static int get_config_tty_dir(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_str(retv, inlen, c->ttydir);
+ return lxc_get_conf_str(retv, inlen, c->ttys.dir);
}
static int get_config_apparmor_profile(const char *key, char *retv, int inlen,
static inline int clr_config_tty_max(const char *key, struct lxc_conf *c,
void *data)
{
- c->tty = 0;
+ c->ttys.tty = 0;
return 0;
}
static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c,
void *data)
{
- free(c->ttydir);
- c->ttydir = NULL;
+ free(c->ttys.dir);
+ c->ttys.dir = NULL;
return 0;
}
return snprintf(retv, inlen, "%d", v);
}
+int lxc_get_conf_size_t(struct lxc_conf *c, char *retv, int inlen, size_t v)
+{
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ return snprintf(retv, inlen, "%zu", v);
+}
+
int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v)
{
if (!retv)
extern bool new_hwaddr(char *hwaddr);
extern int lxc_get_conf_str(char *retv, int inlen, const char *value);
extern int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v);
+extern int lxc_get_conf_size_t(struct lxc_conf *c, char *retv, int inlen, size_t v);
extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v);
extern bool parse_limit_value(const char **value, rlim_t *res);
extern int lxc_inherit_namespace(const char *lxcname_or_pid,
goto out_warn_father;
}
- if (handler->conf->pty_names) {
- ret = putenv(handler->conf->pty_names);
+ if (handler->conf->ttys.tty_names) {
+ ret = putenv(handler->conf->ttys.tty_names);
if (ret < 0) {
SYSERROR("Failed to set environment variable for container ptys");
goto out_warn_father;
struct lxc_conf *conf = handler->conf;
struct lxc_tty_info *ttys = &conf->ttys;
- if (!conf->tty)
+ if (!conf->ttys.max)
return 0;
- ttys->tty = malloc(sizeof(*ttys->tty) * conf->tty);
+ ttys->tty = malloc(sizeof(*ttys->tty) * ttys->max);
if (!ttys->tty)
return -1;
- for (i = 0; i < conf->tty; i++) {
+ for (i = 0; i < conf->ttys.max; i++) {
int ttyfds[2];
ret = lxc_abstract_unix_recv_fds(sock, ttyfds, 2, NULL, 0);
"parent", tty->master, tty->slave);
}
if (ret < 0)
- ERROR("Failed to receive %d ttys from child: %s", conf->tty,
+ ERROR("Failed to receive %zu ttys from child: %s", ttys->max,
strerror(errno));
else
- TRACE("Received %d ttys from child", conf->tty);
-
- ttys->nbtty = conf->tty;
+ TRACE("Received %zu ttys from child", ttys->max);
return ret;
}
}
if (*ttyreq > 0) {
- if (*ttyreq > ttys->nbtty)
+ if (*ttyreq > ttys->max)
goto out;
if (ttys->tty[*ttyreq - 1].busy)
}
/* Search for next available tty, fixup index tty1 => [0]. */
- for (ttynum = 1; ttynum <= ttys->nbtty && ttys->tty[ttynum - 1].busy; ttynum++) {
+ for (ttynum = 1; ttynum <= ttys->max && ttys->tty[ttynum - 1].busy; ttynum++) {
;
}
/* We didn't find any available slot for tty. */
- if (ttynum > ttys->nbtty)
+ if (ttynum > ttys->max)
goto out;
*ttyreq = ttynum;
struct lxc_tty_info *ttys = &conf->ttys;
struct lxc_terminal *terminal = &conf->console;
- for (i = 0; i < ttys->nbtty; i++)
+ for (i = 0; i < ttys->max; i++)
if (ttys->tty[i].busy == fd)
ttys->tty[i].busy = 0;