From 0fc65537a3e103ef0658234cdfa1339160b2a18d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 6 Apr 2010 21:59:19 +0000 Subject: [PATCH] Run job commands explicitly in the global enviroment (which can be modified with setenv -g) rather than with the environment tmux started with. --- environ.c | 40 ++++++++++++++++++++++++++++++++++++++-- job.c | 5 +++-- tmux.1 | 8 ++++++-- tmux.h | 3 ++- window.c | 30 +++++++----------------------- 5 files changed, 56 insertions(+), 30 deletions(-) diff --git a/environ.c b/environ.c index 5c1d2c89..3439a7ab 100644 --- a/environ.c +++ b/environ.c @@ -1,4 +1,4 @@ -/* $Id: environ.c,v 1.3 2009-08-09 17:57:39 tcunha Exp $ */ +/* $Id: environ.c,v 1.4 2010-04-06 21:59:19 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -35,12 +35,14 @@ environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2) return (strcmp(envent1->name, envent2->name)); } +/* Initialise the environment. */ void environ_init(struct environ *env) { RB_INIT(env); } +/* Free an environment. */ void environ_free(struct environ *env) { @@ -56,6 +58,7 @@ environ_free(struct environ *env) } } +/* Copy one environment into another. */ void environ_copy(struct environ *srcenv, struct environ *dstenv) { @@ -65,6 +68,7 @@ environ_copy(struct environ *srcenv, struct environ *dstenv) environ_set(dstenv, envent->name, envent->value); } +/* Find an environment variable. */ struct environ_entry * environ_find(struct environ *env, const char *name) { @@ -74,6 +78,7 @@ environ_find(struct environ *env, const char *name) return (RB_FIND(environ, env, &envent)); } +/* Set an environment variable. */ void environ_set(struct environ *env, const char *name, const char *value) { @@ -97,10 +102,11 @@ environ_set(struct environ *env, const char *name, const char *value) } } +/* Set an environment variable from a NAME=VALUE string. */ void environ_put(struct environ *env, const char *var) { - char *name, *value; + char *name, *value; value = strchr(var, '='); if (value == NULL) @@ -114,6 +120,7 @@ environ_put(struct environ *env, const char *var) xfree(name); } +/* Unset an environment variable. */ void environ_unset(struct environ *env, const char *name) { @@ -128,6 +135,10 @@ environ_unset(struct environ *env, const char *name) xfree(envent); } +/* + * Copy a space-separated list of variables from a destination into a source + * environment. + */ void environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv) { @@ -143,3 +154,28 @@ environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv) } xfree(copyvars); } + +/* Push environment into the real environment - use after fork(). */ +void +environ_push(struct environ *env) +{ + ARRAY_DECL(, char *) varlist; + struct environ_entry *envent; + char **varp, *var; + u_int i; + + ARRAY_INIT(&varlist); + for (varp = environ; *varp != NULL; varp++) { + var = xstrdup(*varp); + var[strcspn(var, "=")] = '\0'; + ARRAY_ADD(&varlist, var); + } + for (i = 0; i < ARRAY_LENGTH(&varlist); i++) + unsetenv(ARRAY_ITEM(&varlist, i)); + ARRAY_FREE(&varlist); + + RB_FOREACH(envent, environ, env) { + if (envent->value != NULL) + setenv(envent->name, envent->value, 1); + } +} diff --git a/job.c b/job.c index 533071fa..59b17fe0 100644 --- a/job.c +++ b/job.c @@ -1,4 +1,4 @@ -/* $Id: job.c,v 1.15 2010-02-26 13:35:04 tcunha Exp $ */ +/* $Id: job.c,v 1.16 2010-04-06 21:59:19 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -149,7 +149,8 @@ job_run(struct job *job) return (-1); case 0: /* child */ server_signal_clear(); - /* XXX environ? */ + + environ_push(&global_environ); if (dup2(out[1], STDOUT_FILENO) == -1) fatal("dup2 failed"); diff --git a/tmux.1 b/tmux.1 index c31cbd34..2f644dbb 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.244 2010-04-05 05:11:44 micahcowan Exp $ +.\" $Id: tmux.1,v 1.245 2010-04-06 21:59:19 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 27 2010 $ +.Dd $Mdocdate: April 4 2010 $ .Dt TMUX 1 .Os .Sh NAME @@ -1743,6 +1743,10 @@ the .Ic status-interval option: if the status line is redrawn in the meantime, the previous result is used. +Shell commands are executed with the +.Nm +global environment set (see the +.Sx ENVIRONMENT section). .Pp #[attributes] allows a comma-separated list of attributes to be specified, these may be diff --git a/tmux.h b/tmux.h index 64490a67..da760776 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.554 2010-04-06 21:58:33 nicm Exp $ */ +/* $Id: tmux.h,v 1.555 2010-04-06 21:59:19 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1330,6 +1330,7 @@ void environ_set(struct environ *, const char *, const char *); void environ_put(struct environ *, const char *); void environ_unset(struct environ *, const char *); void environ_update(const char *, struct environ *, struct environ *); +void environ_push(struct environ *); /* tty.c */ void tty_raw(struct tty *, const char *); diff --git a/window.c b/window.c index 696d25f2..5250b721 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.129 2010-04-06 21:58:33 nicm Exp $ */ +/* $Id: window.c,v 1.130 2010-04-06 21:59:19 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -478,14 +478,11 @@ int window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell, const char *cwd, struct environ *env, struct termios *tio, char **cause) { - struct winsize ws; - int mode; - char *argv0, **varp, *var; - ARRAY_DECL(, char *) varlist; - struct environ_entry *envent; - const char *ptr; - struct termios tio2; - u_int i; + struct winsize ws; + int mode; + char *argv0; + const char *ptr; + struct termios tio2; if (wp->fd != -1) { close(wp->fd); @@ -528,20 +525,7 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell, if (tcsetattr(STDIN_FILENO, TCSANOW, &tio2) != 0) fatal("tcgetattr failed"); - ARRAY_INIT(&varlist); - for (varp = environ; *varp != NULL; varp++) { - var = xstrdup(*varp); - var[strcspn(var, "=")] = '\0'; - ARRAY_ADD(&varlist, var); - } - for (i = 0; i < ARRAY_LENGTH(&varlist); i++) { - var = ARRAY_ITEM(&varlist, i); - unsetenv(var); - } - RB_FOREACH(envent, environ, env) { - if (envent->value != NULL) - setenv(envent->name, envent->value, 1); - } + environ_push(env); server_signal_clear(); log_close();