From 6491274f60c175b89b02b6e4cd0c59b13717e2ec Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 8 Aug 2009 21:52:43 +0000 Subject: Infrastructure and commands to manage the environment for processes started within tmux. There is a global environment, copied from the external environment when the server is started and each sesssion has an (initially empty) session environment which overrides it. New commands set-environment and show-environment manipulate or display the environments. A new session option, update-environment, is a space-separated list of variables which are updated from the external environment into the session environment every time a new session is created - the default is DISPLAY. --- environ.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 environ.c (limited to 'environ.c') diff --git a/environ.c b/environ.c new file mode 100644 index 00000000..e9f95742 --- /dev/null +++ b/environ.c @@ -0,0 +1,147 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2009 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "tmux.h" + +/* + * Environment - manipulate a set of environment variables. + */ + +RB_GENERATE(environ, environ_entry, entry, environ_cmp); + +void environ_set1(struct environ *, char *, char *); + +int +environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2) +{ + return (strcmp(envent1->name, envent2->name)); +} + +void +environ_init(struct environ *env) +{ + RB_INIT(env); +} + +void +environ_free(struct environ *env) +{ + struct environ_entry *envent; + + while (!RB_EMPTY(env)) { + envent = RB_ROOT(env); + RB_REMOVE(environ, env, envent); + xfree(envent->name); + if (envent->value != NULL) + xfree(envent->value); + xfree(envent); + } +} + +void +environ_copy(struct environ *srcenv, struct environ *dstenv) +{ + struct environ_entry *envent; + + RB_FOREACH(envent, environ, srcenv) + environ_set(dstenv, envent->name, envent->value); +} + +struct environ_entry * +environ_find(struct environ *env, const char *name) +{ + struct environ_entry envent; + + envent.name = (char *) name; + return (RB_FIND(environ, env, &envent)); +} + +void +environ_set(struct environ *env, const char *name, const char *value) +{ + struct environ_entry *envent; + + if ((envent = environ_find(env, name)) != NULL) { + if (envent->value != NULL) + xfree(envent->value); + if (value != NULL) + envent->value = xstrdup(value); + else + envent->value = NULL; + } else { + envent = xmalloc(sizeof *envent); + envent->name = xstrdup(name); + if (value != NULL) + envent->value = xstrdup(value); + else + envent->value = NULL; + RB_INSERT(environ, env, envent); + } +} + +void +environ_put(struct environ *env, const char *var) +{ + char *name, *value; + + value = strchr(var, '='); + if (value == NULL) + return; + value++; + + name = xstrdup(var); + name[strcspn(name, "=")] = '\0'; + + environ_set(env, name, value); + xfree(name); +} + +void +environ_unset(struct environ *env, const char *name) +{ + struct environ_entry *envent; + + if ((envent = environ_find(env, name)) == NULL) + return; + RB_REMOVE(environ, env, envent); + xfree(envent->name); + if (envent->value != NULL) + xfree(envent->value); + xfree(envent); +} + +void +environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv) +{ + struct environ_entry *envent; + char *var, *next; + + vars = next = xstrdup(vars); + while ((var = strsep(&next, " ")) != NULL) { + if ((envent = environ_find(srcenv, var)) == NULL) + environ_set(dstenv, var, NULL); + else + environ_set(dstenv, envent->name, envent->value); + } + xfree(vars); +} -- cgit v1.2.3