Make environ_set va_args and use it to tidy up some calls. Also add a

missing word in manpage (from jmc).
pull/218/head
nicm 2015-11-24 23:46:15 +00:00
parent 3ff46b2e43
commit 62d3af17f9
7 changed files with 48 additions and 30 deletions

View File

@ -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"); cmdq_error(cmdq, "can't specify a value with -r");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
environ_set(env, name, NULL); environ_clear(env, name);
} else { } else {
if (value == NULL) { if (value == NULL) {
cmdq_error(cmdq, "no value specified"); cmdq_error(cmdq, "no value specified");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
environ_set(env, name, value); environ_set(env, name, "%s", value);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@ -83,8 +83,12 @@ environ_copy(struct environ *srcenv, struct environ *dstenv)
{ {
struct environ_entry *envent; struct environ_entry *envent;
RB_FOREACH(envent, environ, srcenv) RB_FOREACH(envent, environ, srcenv) {
environ_set(dstenv, envent->name, envent->value); if (envent->value == NULL)
environ_clear(dstenv, envent->name);
else
environ_set(dstenv, envent->name, "%s", envent->value);
}
} }
/* Find an environment variable. */ /* Find an environment variable. */
@ -99,23 +103,37 @@ environ_find(struct environ *env, const char *name)
/* Set an environment variable. */ /* 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 *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; struct environ_entry *envent;
if ((envent = environ_find(env, name)) != NULL) { if ((envent = environ_find(env, name)) != NULL) {
free(envent->value); free(envent->value);
if (value != NULL) envent->value = NULL;
envent->value = xstrdup(value);
else
envent->value = NULL;
} else { } else {
envent = xmalloc(sizeof *envent); envent = xmalloc(sizeof *envent);
envent->name = xstrdup(name); envent->name = xstrdup(name);
if (value != NULL) envent->value = NULL;
envent->value = xstrdup(value);
else
envent->value = NULL;
RB_INSERT(environ, env, envent); RB_INSERT(environ, env, envent);
} }
} }
@ -134,7 +152,7 @@ environ_put(struct environ *env, const char *var)
name = xstrdup(var); name = xstrdup(var);
name[strcspn(name, "=")] = '\0'; name[strcspn(name, "=")] = '\0';
environ_set(env, name, value); environ_set(env, name, "%s", value);
free(name); free(name);
} }
@ -166,9 +184,9 @@ environ_update(const char *vars, struct environ *srcenv,
copyvars = next = xstrdup(vars); copyvars = next = xstrdup(vars);
while ((var = strsep(&next, " ")) != NULL) { while ((var = strsep(&next, " ")) != NULL) {
if ((envent = environ_find(srcenv, var)) == NULL) if ((envent = environ_find(srcenv, var)) == NULL)
environ_set(dstenv, var, NULL); environ_clear(dstenv, var);
else else
environ_set(dstenv, envent->name, envent->value); environ_set(dstenv, envent->name, "%s", envent->value);
} }
free(copyvars); free(copyvars);
} }

View File

@ -34,20 +34,19 @@ void server_callback_identify(int, short, void *);
void void
server_fill_environ(struct session *s, struct environ *env) server_fill_environ(struct session *s, struct environ *env)
{ {
char var[PATH_MAX], *term; char *term;
u_int idx; u_int idx;
long pid; long pid;
if (s != NULL) { if (s != NULL) {
term = options_get_string(global_options, "default-terminal"); term = options_get_string(global_options, "default-terminal");
environ_set(env, "TERM", term); environ_set(env, "TERM", "%s", term);
idx = s->id; idx = s->id;
} else } else
idx = (u_int)-1; idx = (u_int)-1;
pid = getpid(); pid = getpid();
xsnprintf(var, sizeof var, "%s,%ld,%u", socket_path, pid, idx); environ_set(env, "TMUX", "%s,%ld,%u", socket_path, pid, idx);
environ_set(env, "TMUX", var);
} }
void void

2
tmux.1
View File

@ -750,7 +750,7 @@ If
is given, all sessions but the specified one is killed. is given, all sessions but the specified one is killed.
The The
.Fl C .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. session.
.It Xo Ic list-clients .It Xo Ic list-clients
.Op Fl F Ar format .Op Fl F Ar format

2
tmux.c
View File

@ -273,7 +273,7 @@ main(int argc, char **argv)
for (var = environ; *var != NULL; var++) for (var = environ; *var != NULL; var++)
environ_put(global_environ, *var); environ_put(global_environ, *var);
if (getcwd(tmp, sizeof tmp) != NULL) if (getcwd(tmp, sizeof tmp) != NULL)
environ_set(global_environ, "PWD", tmp); environ_set(global_environ, "PWD", "%s", tmp);
global_options = options_create(NULL); global_options = options_create(NULL);
options_table_populate_tree(OPTIONS_TABLE_SERVER, global_options); options_table_populate_tree(OPTIONS_TABLE_SERVER, global_options);

6
tmux.h
View File

@ -1567,7 +1567,9 @@ struct environ_entry *environ_first(struct environ *);
struct environ_entry *environ_next(struct environ_entry *); struct environ_entry *environ_next(struct environ_entry *);
void environ_copy(struct environ *, struct environ *); void environ_copy(struct environ *, struct environ *);
struct environ_entry *environ_find(struct environ *, const char *); 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_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 *);
@ -1739,7 +1741,7 @@ RB_PROTOTYPE(key_tables, key_table, entry, key_table_cmp);
extern struct key_tables key_tables; extern struct key_tables key_tables;
int key_table_cmp(struct key_table *, struct key_table *); int key_table_cmp(struct key_table *, struct key_table *);
int key_bindings_cmp(struct key_binding *, struct key_binding *); 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_unref_table(struct key_table *);
void key_bindings_add(const char *, key_code, int, struct cmd_list *); void key_bindings_add(const char *, key_code, int, struct cmd_list *);
void key_bindings_remove(const char *, key_code); void key_bindings_remove(const char *, key_code);

View File

@ -808,7 +808,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
struct termios *tio, char **cause) struct termios *tio, char **cause)
{ {
struct winsize ws; struct winsize ws;
char *argv0, *cmd, **argvp, paneid[16]; char *argv0, *cmd, **argvp;
const char *ptr, *first, *home; const char *ptr, *first, *home;
struct termios tio2; struct termios tio2;
int i; int i;
@ -863,9 +863,8 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
closefrom(STDERR_FILENO + 1); closefrom(STDERR_FILENO + 1);
if (path != NULL) if (path != NULL)
environ_set(env, "PATH", path); environ_set(env, "PATH", "%s", path);
xsnprintf(paneid, sizeof paneid, "%%%u", wp->id); environ_set(env, "TMUX_PANE", "%%%u", wp->id);
environ_set(env, "TMUX_PANE", paneid);
environ_push(env); environ_push(env);
clear_signals(1); clear_signals(1);