Run job commands explicitly in the global enviroment (which can be

modified with setenv -g) rather than with the environment tmux started
with.
pull/1/head
Nicholas Marriott 2010-04-06 21:59:19 +00:00
parent 091db41bc9
commit 0fc65537a3
5 changed files with 56 additions and 30 deletions

View File

@ -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 <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -35,12 +35,14 @@ environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2)
return (strcmp(envent1->name, envent2->name)); return (strcmp(envent1->name, envent2->name));
} }
/* Initialise the environment. */
void void
environ_init(struct environ *env) environ_init(struct environ *env)
{ {
RB_INIT(env); RB_INIT(env);
} }
/* Free an environment. */
void void
environ_free(struct environ *env) environ_free(struct environ *env)
{ {
@ -56,6 +58,7 @@ environ_free(struct environ *env)
} }
} }
/* Copy one environment into another. */
void void
environ_copy(struct environ *srcenv, struct environ *dstenv) 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); environ_set(dstenv, envent->name, envent->value);
} }
/* Find an environment variable. */
struct environ_entry * struct environ_entry *
environ_find(struct environ *env, const char *name) 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)); return (RB_FIND(environ, env, &envent));
} }
/* Set an environment variable. */
void void
environ_set(struct environ *env, const char *name, const char *value) 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 void
environ_put(struct environ *env, const char *var) environ_put(struct environ *env, const char *var)
{ {
char *name, *value; char *name, *value;
value = strchr(var, '='); value = strchr(var, '=');
if (value == NULL) if (value == NULL)
@ -114,6 +120,7 @@ environ_put(struct environ *env, const char *var)
xfree(name); xfree(name);
} }
/* Unset an environment variable. */
void void
environ_unset(struct environ *env, const char *name) environ_unset(struct environ *env, const char *name)
{ {
@ -128,6 +135,10 @@ environ_unset(struct environ *env, const char *name)
xfree(envent); xfree(envent);
} }
/*
* Copy a space-separated list of variables from a destination into a source
* environment.
*/
void void
environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv) 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); 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);
}
}

5
job.c
View File

@ -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 <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -149,7 +149,8 @@ job_run(struct job *job)
return (-1); return (-1);
case 0: /* child */ case 0: /* child */
server_signal_clear(); server_signal_clear();
/* XXX environ? */
environ_push(&global_environ);
if (dup2(out[1], STDOUT_FILENO) == -1) if (dup2(out[1], STDOUT_FILENO) == -1)
fatal("dup2 failed"); fatal("dup2 failed");

8
tmux.1
View File

@ -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 <nicm@users.sourceforge.net> .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\" .\"
@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" 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 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@ -1743,6 +1743,10 @@ the
.Ic status-interval .Ic status-interval
option: if the status line is redrawn in the meantime, the previous result is option: if the status line is redrawn in the meantime, the previous result is
used. used.
Shell commands are executed with the
.Nm
global environment set (see the
.Sx ENVIRONMENT section).
.Pp .Pp
#[attributes] allows a comma-separated list of attributes to be specified, #[attributes] allows a comma-separated list of attributes to be specified,
these may be these may be

3
tmux.h
View File

@ -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 <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1330,6 +1330,7 @@ void environ_set(struct environ *, const char *, const char *);
void environ_put(struct environ *, const char *); void environ_put(struct environ *, const char *);
void environ_unset(struct environ *, const char *); void environ_unset(struct environ *, const char *);
void environ_update(const char *, struct environ *, struct environ *); void environ_update(const char *, struct environ *, struct environ *);
void environ_push(struct environ *);
/* tty.c */ /* tty.c */
void tty_raw(struct tty *, const char *); void tty_raw(struct tty *, const char *);

View File

@ -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 <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -478,14 +478,11 @@ int
window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell, window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
const char *cwd, struct environ *env, struct termios *tio, char **cause) const char *cwd, struct environ *env, struct termios *tio, char **cause)
{ {
struct winsize ws; struct winsize ws;
int mode; int mode;
char *argv0, **varp, *var; char *argv0;
ARRAY_DECL(, char *) varlist; const char *ptr;
struct environ_entry *envent; struct termios tio2;
const char *ptr;
struct termios tio2;
u_int i;
if (wp->fd != -1) { if (wp->fd != -1) {
close(wp->fd); 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) if (tcsetattr(STDIN_FILENO, TCSANOW, &tio2) != 0)
fatal("tcgetattr failed"); fatal("tcgetattr failed");
ARRAY_INIT(&varlist); environ_push(env);
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);
}
server_signal_clear(); server_signal_clear();
log_close(); log_close();