char **extra_env, char **extra_keep)
{
int ret;
- struct lxc_list *iterator;
if (policy == LXC_ATTACH_CLEAR_ENV) {
int path_kept = 0;
/* Set container environment variables.*/
if (ctx->container->lxc_conf) {
- lxc_list_for_each(iterator, &ctx->container->lxc_conf->environment) {
- char *env_tmp;
-
- env_tmp = strdup((char *)iterator->elem);
- if (!env_tmp)
- return -1;
-
- ret = putenv(env_tmp);
- if (ret < 0)
- return log_error_errno(-1, errno, "Failed to set environment variable: %s", (char *)iterator->elem);
- }
+ ret = lxc_set_environment(ctx->container->lxc_conf);
+ if (ret < 0)
+ return -1;
}
/* Set extra environment variables. */
INIT_LIST_HEAD(&new->id_map);
new->root_nsuid_map = NULL;
new->root_nsgid_map = NULL;
- lxc_list_init(&new->environment);
+ INIT_LIST_HEAD(&new->environment);
INIT_LIST_HEAD(&new->limits);
INIT_LIST_HEAD(&new->sysctls);
INIT_LIST_HEAD(&new->procs);
int lxc_clear_environment(struct lxc_conf *c)
{
- struct lxc_list *it, *next;
+ struct environment_entry *env, *nenv;
- lxc_list_for_each_safe (it, &c->environment, next) {
- lxc_list_del(it);
- free(it->elem);
- free(it);
+ list_for_each_entry_safe(env, nenv, &c->environment, head) {
+ list_del(&env->head);
+ free(env->key);
+ free(env->val);
+ free(env);
}
- lxc_list_init(&c->environment);
+ INIT_LIST_HEAD(&c->environment);
return 0;
}
}
}
}
+
+int lxc_set_environment(const struct lxc_conf *conf)
+{
+ struct environment_entry *env;
+
+ list_for_each_entry(env, &conf->environment, head) {
+ int ret;
+
+ ret = setenv(env->key, env->val, 1);
+ if (ret < 0)
+ return syserror("Failed to set environment variable: %s=%s",
+ env->key, env->val);
+ TRACE("Set environment variable: %s=%s", env->key, env->val);
+ }
+
+ return 0;
+}
int64_t ns_monotonic;
};
+struct environment_entry {
+ char *key;
+ char *val;
+ struct list_head head;
+};
+
struct lxc_conf {
/* Pointer to the name of the container. Do not free! */
const char *name;
/* list of environment variables we'll add to the container when
* started */
- struct lxc_list environment;
+ struct list_head environment;
/* text representation of the config file */
char *unexpanded_config;
return personality(persona);
}
+__hidden extern int lxc_set_environment(const struct lxc_conf *conf);
+
#endif /* __LXC_CONF_H */
static int set_config_environment(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- __do_free struct lxc_list *list_item = NULL;
+ __do_free char *dup = NULL, *val = NULL;
+ __do_free struct environment_entry *new_env = NULL;
+ char *env_val;
if (lxc_config_value_empty(value))
return lxc_clear_environment(lxc_conf);
- list_item = lxc_list_new();
- if (!list_item)
+ new_env = zalloc(sizeof(struct environment_entry));
+ if (!new_env)
return ret_errno(ENOMEM);
- if (!strchr(value, '=')) {
- const char *env_val;
- const char *env_key = value;
- const char *env_var[3] = {0};
-
- env_val = getenv(env_key);
- if (!env_val)
- return ret_errno(ENOENT);
+ dup = strdup(value);
+ if (!dup)
+ return ret_errno(ENOMEM);
- env_var[0] = env_key;
- env_var[1] = env_val;
- list_item->elem = lxc_string_join("=", env_var, false);
+ env_val = strchr(dup, '=');
+ if (!env_val) {
+ env_val = getenv(dup);
} else {
- list_item->elem = strdup(value);
+ *env_val = '\0';
+ env_val++;
}
+ if (!env_val)
+ return ret_errno(ENOENT);
- if (!list_item->elem)
+ val = strdup(env_val);
+ if (!val)
return ret_errno(ENOMEM);
- lxc_list_add_tail(&lxc_conf->environment, move_ptr(list_item));
+ new_env->key = move_ptr(dup);
+ new_env->val = move_ptr(val);
+
+ list_add_tail(&new_env->head, &lxc_conf->environment);
+ move_ptr(new_env);
return 0;
}
struct lxc_conf *c, void *data)
{
int len, fulllen = 0;
- struct lxc_list *it;
+ struct environment_entry *env;
if (!retv)
inlen = 0;
else
memset(retv, 0, inlen);
- lxc_list_for_each(it, &c->environment) {
- strprint(retv, inlen, "%s\n", (char *)it->elem);
+ list_for_each_entry(env, &c->environment, head) {
+ strprint(retv, inlen, "%s=%s\n", env->key, env->val);
}
return fulllen;
{
struct lxc_handler *handler = data;
__lxc_unused __do_close int data_sock0 = handler->data_sock[0],
- data_sock1 = handler->data_sock[1];
+ data_sock1 = handler->data_sock[1];
__do_close int devnull_fd = -EBADF, status_fd = -EBADF;
int ret;
uid_t new_uid;
gid_t new_gid;
- struct lxc_list *iterator;
uid_t nsuid = 0;
gid_t nsgid = 0;
}
}
- /* Add the requested environment variables to the current environment to
- * allow them to be used by the various hooks, such as the start hook
- * below.
+ /*
+ * Add the requested environment variables to the current environment
+ * to allow them to be used by the various hooks, such as the start
+ * hook below.
*/
- lxc_list_for_each(iterator, &handler->conf->environment) {
- ret = putenv((char *)iterator->elem);
- if (ret < 0) {
- SYSERROR("Failed to set environment variable: %s",
- (char *)iterator->elem);
- goto out_warn_father;
- }
- }
+ ret = lxc_set_environment(handler->conf);
+ if (ret < 0)
+ goto out_warn_father;
if (!lxc_sync_wait_parent(handler, START_SYNC_POST_CONFIGURE))
goto out_warn_father;
if (ret < 0)
SYSERROR("Failed to clear environment.");
- lxc_list_for_each(iterator, &handler->conf->environment) {
- ret = putenv((char *)iterator->elem);
- if (ret < 0) {
- SYSERROR("Failed to set environment variable: %s",
- (char *)iterator->elem);
- goto out_warn_father;
- }
- }
+ ret = lxc_set_environment(handler->conf);
+ if (ret < 0)
+ goto out_warn_father;
ret = putenv("container=lxc");
if (ret < 0) {