diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 5807eefc..f61b5930 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -54,7 +54,6 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, struct client *c = item->client, *c_loop; struct winlink *wl = item->state.tflag.wl; struct window_pane *wp = item->state.tflag.wp; - const char *update; char *cause, *cwd; struct format_tree *ft; @@ -95,12 +94,8 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, server_client_detach(c_loop, MSG_DETACH); } } - - if (!Eflag) { - update = options_get_string(s->options, - "update-environment"); - environ_update(update, c->environ, s->environ); - } + if (!Eflag) + environ_update(s->options, c->environ, s->environ); c->session = s; server_client_set_key_table(c, NULL); @@ -116,7 +111,6 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, free(cause); return (CMD_RETURN_ERROR); } - if (rflag) c->flags |= CLIENT_READONLY; @@ -127,12 +121,8 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, server_client_detach(c_loop, MSG_DETACH); } } - - if (!Eflag) { - update = options_get_string(s->options, - "update-environment"); - environ_update(update, c->environ, s->environ); - } + if (!Eflag) + environ_update(s->options, c->environ, s->environ); c->session = s; server_client_set_key_table(c, NULL); diff --git a/cmd-new-session.c b/cmd-new-session.c index 7df7dcb6..10304bc0 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -73,7 +73,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) struct window *w; struct environ *env; struct termios tio, *tiop; - const char *newname, *target, *update, *errstr, *template; + const char *newname, *target, *errstr, *template; const char *path, *cmd, *cwd, *to_free = NULL; char **argv, *cause, *cp; int detached, already_attached, idx, argc; @@ -234,11 +234,8 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) /* Construct the environment. */ env = environ_create(); - if (c != NULL && !args_has(args, 'E')) { - update = options_get_string(global_s_options, - "update-environment"); - environ_update(update, c->environ, env); - } + if (c != NULL && !args_has(args, 'E')) + environ_update(global_s_options, c->environ, env); /* Create the new session. */ idx = -1 - options_get_number(global_s_options, "base-index"); diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 81f70d9c..cd46db39 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -53,7 +53,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) struct client *c = state->c; struct session *s = item->state.tflag.s; struct window_pane *wp; - const char *tablename, *update; + const char *tablename; struct key_table *table; if (args_has(args, 'r')) @@ -102,10 +102,8 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) } } - if (!args_has(args, 'E')) { - update = options_get_string(s->options, "update-environment"); - environ_update(update, c->environ, s->environ); - } + if (!args_has(args, 'E')) + environ_update(s->options, c->environ, s->environ); if (c->session != NULL && c->session != s) c->last_session = c->session; diff --git a/environ.c b/environ.c index 016d256a..4bb794dd 100644 --- a/environ.c +++ b/environ.c @@ -169,25 +169,27 @@ environ_unset(struct environ *env, const char *name) free(envent); } -/* - * Copy a space-separated list of variables from a destination into a source - * environment. - */ +/* Copy variables from a destination into a source * environment. */ void -environ_update(const char *vars, struct environ *srcenv, - struct environ *dstenv) +environ_update(struct options *oo, struct environ *src, struct environ *dst) { struct environ_entry *envent; - char *copyvars, *var, *next; + struct options_entry *o; + u_int size, idx; + const char *value; - copyvars = next = xstrdup(vars); - while ((var = strsep(&next, " ")) != NULL) { - if ((envent = environ_find(srcenv, var)) == NULL) - environ_clear(dstenv, var); + o = options_get(oo, "update-environment"); + if (o == NULL || options_array_size(o, &size) == -1) + return; + for (idx = 0; idx < size; idx++) { + value = options_array_get(o, idx); + if (value == NULL) + continue; + if ((envent = environ_find(src, value)) == NULL) + environ_clear(dst, value); else - environ_set(dstenv, envent->name, "%s", envent->value); + environ_set(dst, envent->name, "%s", envent->value); } - free(copyvars); } /* Push environment into the real environment - use after fork(). */ diff --git a/options-table.c b/options-table.c index 2b506b8c..8af4d934 100644 --- a/options-table.c +++ b/options-table.c @@ -482,11 +482,10 @@ const struct options_table_entry options_table[] = { }, { .name = "update-environment", - .type = OPTIONS_TABLE_STRING, + .type = OPTIONS_TABLE_ARRAY, .scope = OPTIONS_TABLE_SESSION, .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID " "SSH_CONNECTION WINDOWID XAUTHORITY" - }, { .name = "visual-activity", diff --git a/tmux.1 b/tmux.1 index f30b45f1..6f680fdf 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2869,19 +2869,15 @@ For how to specify see the .Ic message-command-style option. -.It Ic update-environment Ar variables -Set a space-separated string containing a list of environment variables to be -copied into the session environment when a new session is created or an -existing session is attached. +.It Ic update-environment[] Ar variable +Set list of environment variables to be copied into the session environment +when a new session is created or an existing session is attached. Any variables that do not exist in the source environment are set to be removed from the session environment (as if .Fl r was given to the .Ic set-environment command). -The default is -"DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID -XAUTHORITY". .It Xo Ic visual-activity .Op Ic on | off .Xc diff --git a/tmux.h b/tmux.h index 20ec044a..4a82871f 100644 --- a/tmux.h +++ b/tmux.h @@ -1669,7 +1669,7 @@ void printflike(3, 4) environ_set(struct environ *, const char *, const char *, void environ_clear(struct environ *, 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_update(struct options *, struct environ *, struct environ *); void environ_push(struct environ *); void environ_log(struct environ *, const char *);