diff --git a/environ.c b/environ.c index 353b84fa..4c4af98f 100644 --- a/environ.c +++ b/environ.c @@ -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 36ea2f4e..ddeae13f 100644 --- a/job.c +++ b/job.c @@ -150,7 +150,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 351aec44..dc590c7e 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1745,6 +1745,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 576c4977..642d5530 100644 --- a/tmux.h +++ b/tmux.h @@ -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 4a801a76..00c03f6e 100644 --- a/window.c +++ b/window.c @@ -480,14 +480,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); @@ -530,20 +527,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();