diff --git a/cmd-set-environment.c b/cmd-set-environment.c index 864e1d9b..2c0010af 100644 --- a/cmd-set-environment.c +++ b/cmd-set-environment.c @@ -79,13 +79,13 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) cmdq_error(cmdq, "can't specify a value with -r"); return (CMD_RETURN_ERROR); } - environ_set(env, name, NULL); + environ_clear(env, name); } else { if (value == NULL) { cmdq_error(cmdq, "no value specified"); return (CMD_RETURN_ERROR); } - environ_set(env, name, value); + environ_set(env, name, "%s", value); } return (CMD_RETURN_NORMAL); diff --git a/environ.c b/environ.c index 43a9ce01..de560896 100644 --- a/environ.c +++ b/environ.c @@ -83,8 +83,12 @@ environ_copy(struct environ *srcenv, struct environ *dstenv) { struct environ_entry *envent; - RB_FOREACH(envent, environ, srcenv) - environ_set(dstenv, envent->name, envent->value); + RB_FOREACH(envent, environ, srcenv) { + if (envent->value == NULL) + environ_clear(dstenv, envent->name); + else + environ_set(dstenv, envent->name, "%s", envent->value); + } } /* Find an environment variable. */ @@ -99,23 +103,37 @@ environ_find(struct environ *env, const char *name) /* Set an environment variable. */ void -environ_set(struct environ *env, const char *name, const char *value) +environ_set(struct environ *env, const char *name, const char *fmt, ...) +{ + struct environ_entry *envent; + va_list ap; + + va_start(ap, fmt); + if ((envent = environ_find(env, name)) != NULL) { + free(envent->value); + xvasprintf(&envent->value, fmt, ap); + } else { + envent = xmalloc(sizeof *envent); + envent->name = xstrdup(name); + xvasprintf(&envent->value, fmt, ap); + RB_INSERT(environ, env, envent); + } + va_end(ap); +} + +/* Clear an environment variable. */ +void +environ_clear(struct environ *env, const char *name) { struct environ_entry *envent; if ((envent = environ_find(env, name)) != NULL) { free(envent->value); - if (value != NULL) - envent->value = xstrdup(value); - else - envent->value = NULL; + envent->value = NULL; } else { envent = xmalloc(sizeof *envent); envent->name = xstrdup(name); - if (value != NULL) - envent->value = xstrdup(value); - else - envent->value = NULL; + envent->value = NULL; RB_INSERT(environ, env, envent); } } @@ -134,7 +152,7 @@ environ_put(struct environ *env, const char *var) name = xstrdup(var); name[strcspn(name, "=")] = '\0'; - environ_set(env, name, value); + environ_set(env, name, "%s", value); free(name); } @@ -166,9 +184,9 @@ environ_update(const char *vars, struct environ *srcenv, copyvars = next = xstrdup(vars); while ((var = strsep(&next, " ")) != NULL) { if ((envent = environ_find(srcenv, var)) == NULL) - environ_set(dstenv, var, NULL); + environ_clear(dstenv, var); else - environ_set(dstenv, envent->name, envent->value); + environ_set(dstenv, envent->name, "%s", envent->value); } free(copyvars); } diff --git a/server-fn.c b/server-fn.c index 3e4b6116..a22c964d 100644 --- a/server-fn.c +++ b/server-fn.c @@ -34,20 +34,19 @@ void server_callback_identify(int, short, void *); void server_fill_environ(struct session *s, struct environ *env) { - char var[PATH_MAX], *term; - u_int idx; - long pid; + char *term; + u_int idx; + long pid; if (s != NULL) { term = options_get_string(global_options, "default-terminal"); - environ_set(env, "TERM", term); + environ_set(env, "TERM", "%s", term); idx = s->id; } else idx = (u_int)-1; pid = getpid(); - xsnprintf(var, sizeof var, "%s,%ld,%u", socket_path, pid, idx); - environ_set(env, "TMUX", var); + environ_set(env, "TMUX", "%s,%ld,%u", socket_path, pid, idx); } void diff --git a/tmux.1 b/tmux.1 index 8fa6ad55..454af1d2 100644 --- a/tmux.1 +++ b/tmux.1 @@ -750,7 +750,7 @@ If is given, all sessions but the specified one is killed. The .Fl C -clears alerts (bell, activity, or silence) in all windows linked to the +flag clears alerts (bell, activity, or silence) in all windows linked to the session. .It Xo Ic list-clients .Op Fl F Ar format diff --git a/tmux.c b/tmux.c index 7d49dd30..68f0092d 100644 --- a/tmux.c +++ b/tmux.c @@ -273,7 +273,7 @@ main(int argc, char **argv) for (var = environ; *var != NULL; var++) environ_put(global_environ, *var); if (getcwd(tmp, sizeof tmp) != NULL) - environ_set(global_environ, "PWD", tmp); + environ_set(global_environ, "PWD", "%s", tmp); global_options = options_create(NULL); options_table_populate_tree(OPTIONS_TABLE_SERVER, global_options); diff --git a/tmux.h b/tmux.h index f4638bc8..2acfc75f 100644 --- a/tmux.h +++ b/tmux.h @@ -1567,7 +1567,9 @@ struct environ_entry *environ_first(struct environ *); struct environ_entry *environ_next(struct environ_entry *); void environ_copy(struct environ *, struct environ *); struct environ_entry *environ_find(struct environ *, const char *); -void environ_set(struct environ *, const char *, const char *); +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 *); @@ -1739,7 +1741,7 @@ RB_PROTOTYPE(key_tables, key_table, entry, key_table_cmp); extern struct key_tables key_tables; int key_table_cmp(struct key_table *, struct key_table *); int key_bindings_cmp(struct key_binding *, struct key_binding *); -struct key_table *key_bindings_get_table(const char *, int); +struct key_table *key_bindings_get_table(const char *, int); void key_bindings_unref_table(struct key_table *); void key_bindings_add(const char *, key_code, int, struct cmd_list *); void key_bindings_remove(const char *, key_code); diff --git a/window.c b/window.c index 8ee517a1..deda2895 100644 --- a/window.c +++ b/window.c @@ -808,7 +808,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, struct termios *tio, char **cause) { struct winsize ws; - char *argv0, *cmd, **argvp, paneid[16]; + char *argv0, *cmd, **argvp; const char *ptr, *first, *home; struct termios tio2; int i; @@ -863,9 +863,8 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, closefrom(STDERR_FILENO + 1); if (path != NULL) - environ_set(env, "PATH", path); - xsnprintf(paneid, sizeof paneid, "%%%u", wp->id); - environ_set(env, "TMUX_PANE", paneid); + environ_set(env, "PATH", "%s", path); + environ_set(env, "TMUX_PANE", "%%%u", wp->id); environ_push(env); clear_signals(1);