mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Add a way to mark environment variables as "hidden" so they can be used
by tmux but are not passed into the environment of new panes.
This commit is contained in:
parent
e6cddcf752
commit
cc8b41f294
@ -81,7 +81,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
add = args_first_value(args, 'e', &value);
|
||||
while (add != NULL) {
|
||||
environ_put(sc.environ, add);
|
||||
environ_put(sc.environ, add, 0);
|
||||
add = args_next_value(&value);
|
||||
}
|
||||
|
||||
|
23
cmd-parse.y
23
cmd-parse.y
@ -99,6 +99,7 @@ static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
|
||||
}
|
||||
|
||||
%token ERROR
|
||||
%token HIDDEN
|
||||
%token IF
|
||||
%token ELSE
|
||||
%token ELIF
|
||||
@ -134,6 +135,11 @@ statements : statement '\n'
|
||||
}
|
||||
|
||||
statement : /* empty */
|
||||
{
|
||||
$$ = xmalloc (sizeof *$$);
|
||||
TAILQ_INIT($$);
|
||||
}
|
||||
| hidden_assignment
|
||||
{
|
||||
$$ = xmalloc (sizeof *$$);
|
||||
TAILQ_INIT($$);
|
||||
@ -204,10 +210,21 @@ assignment : EQUALS
|
||||
|
||||
if ((~flags & CMD_PARSE_PARSEONLY) &&
|
||||
(ps->scope == NULL || ps->scope->flag))
|
||||
environ_put(global_environ, $1);
|
||||
environ_put(global_environ, $1, 0);
|
||||
free($1);
|
||||
}
|
||||
|
||||
hidden_assignment : HIDDEN EQUALS
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
int flags = ps->input->flags;
|
||||
|
||||
if ((~flags & CMD_PARSE_PARSEONLY) &&
|
||||
(ps->scope == NULL || ps->scope->flag))
|
||||
environ_put(global_environ, $2, ENVIRON_HIDDEN);
|
||||
free($2);
|
||||
}
|
||||
|
||||
if_open : IF expanded
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
@ -1079,6 +1096,10 @@ yylex(void)
|
||||
if (*cp == '\0')
|
||||
return (TOKEN);
|
||||
ps->condition = 1;
|
||||
if (strcmp(yylval.token, "%hidden") == 0) {
|
||||
free(yylval.token);
|
||||
return (HIDDEN);
|
||||
}
|
||||
if (strcmp(yylval.token, "%if") == 0) {
|
||||
free(yylval.token);
|
||||
return (IF);
|
||||
|
@ -71,7 +71,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
add = args_first_value(args, 'e', &value);
|
||||
while (add != NULL) {
|
||||
environ_put(sc.environ, add);
|
||||
environ_put(sc.environ, add, 0);
|
||||
add = args_next_value(&value);
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
add = args_first_value(args, 'e', &value);
|
||||
while (add != NULL) {
|
||||
environ_put(sc.environ, add);
|
||||
environ_put(sc.environ, add, 0);
|
||||
add = args_next_value(&value);
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@ const struct cmd_entry cmd_set_environment_entry = {
|
||||
.name = "set-environment",
|
||||
.alias = "setenv",
|
||||
|
||||
.args = { "grt:u", 1, 2 },
|
||||
.usage = "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
|
||||
.args = { "hgrt:u", 1, 2 },
|
||||
.usage = "[-hgru] " CMD_TARGET_SESSION_USAGE " name [value]",
|
||||
|
||||
.target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL },
|
||||
|
||||
@ -96,7 +96,10 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item)
|
||||
cmdq_error(item, "no value specified");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
environ_set(env, name, "%s", value);
|
||||
if (args_has(args, 'h'))
|
||||
environ_set(env, name, ENVIRON_HIDDEN, "%s", value);
|
||||
else
|
||||
environ_set(env, name, 0, "%s", value);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
@ -38,8 +38,8 @@ const struct cmd_entry cmd_show_environment_entry = {
|
||||
.name = "show-environment",
|
||||
.alias = "showenv",
|
||||
|
||||
.args = { "gst:", 0, 1 },
|
||||
.usage = "[-gs] " CMD_TARGET_SESSION_USAGE " [name]",
|
||||
.args = { "hgst:", 0, 1 },
|
||||
.usage = "[-hgs] " CMD_TARGET_SESSION_USAGE " [name]",
|
||||
|
||||
.target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL },
|
||||
|
||||
@ -69,7 +69,13 @@ static void
|
||||
cmd_show_environment_print(struct cmd *self, struct cmdq_item *item,
|
||||
struct environ_entry *envent)
|
||||
{
|
||||
char *escaped;
|
||||
struct args *args = self->args;
|
||||
char *escaped;
|
||||
|
||||
if (!args_has(args, 'h') && (envent->flags & ENVIRON_HIDDEN))
|
||||
return;
|
||||
if (args_has(args, 'h') && (~envent->flags & ENVIRON_HIDDEN))
|
||||
return;
|
||||
|
||||
if (!args_has(self->args, 's')) {
|
||||
if (envent->value != NULL)
|
||||
|
@ -142,7 +142,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
add = args_first_value(args, 'e', &value);
|
||||
while (add != NULL) {
|
||||
environ_put(sc.environ, add);
|
||||
environ_put(sc.environ, add, 0);
|
||||
add = args_next_value(&value);
|
||||
}
|
||||
|
||||
|
29
environ.c
29
environ.c
@ -86,8 +86,10 @@ environ_copy(struct environ *srcenv, struct environ *dstenv)
|
||||
RB_FOREACH(envent, environ, srcenv) {
|
||||
if (envent->value == NULL)
|
||||
environ_clear(dstenv, envent->name);
|
||||
else
|
||||
environ_set(dstenv, envent->name, "%s", envent->value);
|
||||
else {
|
||||
environ_set(dstenv, envent->name, envent->flags,
|
||||
"%s", envent->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,18 +105,21 @@ environ_find(struct environ *env, const char *name)
|
||||
|
||||
/* Set an environment variable. */
|
||||
void
|
||||
environ_set(struct environ *env, const char *name, const char *fmt, ...)
|
||||
environ_set(struct environ *env, const char *name, int flags, const char *fmt,
|
||||
...)
|
||||
{
|
||||
struct environ_entry *envent;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if ((envent = environ_find(env, name)) != NULL) {
|
||||
envent->flags = flags;
|
||||
free(envent->value);
|
||||
xvasprintf(&envent->value, fmt, ap);
|
||||
} else {
|
||||
envent = xmalloc(sizeof *envent);
|
||||
envent->name = xstrdup(name);
|
||||
envent->flags = flags;
|
||||
xvasprintf(&envent->value, fmt, ap);
|
||||
RB_INSERT(environ, env, envent);
|
||||
}
|
||||
@ -133,6 +138,7 @@ environ_clear(struct environ *env, const char *name)
|
||||
} else {
|
||||
envent = xmalloc(sizeof *envent);
|
||||
envent->name = xstrdup(name);
|
||||
envent->flags = 0;
|
||||
envent->value = NULL;
|
||||
RB_INSERT(environ, env, envent);
|
||||
}
|
||||
@ -140,7 +146,7 @@ environ_clear(struct environ *env, const char *name)
|
||||
|
||||
/* Set an environment variable from a NAME=VALUE string. */
|
||||
void
|
||||
environ_put(struct environ *env, const char *var)
|
||||
environ_put(struct environ *env, const char *var, int flags)
|
||||
{
|
||||
char *name, *value;
|
||||
|
||||
@ -152,7 +158,7 @@ environ_put(struct environ *env, const char *var)
|
||||
name = xstrdup(var);
|
||||
name[strcspn(name, "=")] = '\0';
|
||||
|
||||
environ_set(env, name, "%s", value);
|
||||
environ_set(env, name, flags, "%s", value);
|
||||
free(name);
|
||||
}
|
||||
|
||||
@ -170,7 +176,7 @@ environ_unset(struct environ *env, const char *name)
|
||||
free(envent);
|
||||
}
|
||||
|
||||
/* Copy variables from a destination into a source * environment. */
|
||||
/* Copy variables from a destination into a source environment. */
|
||||
void
|
||||
environ_update(struct options *oo, struct environ *src, struct environ *dst)
|
||||
{
|
||||
@ -188,7 +194,7 @@ environ_update(struct options *oo, struct environ *src, struct environ *dst)
|
||||
if ((envent = environ_find(src, ov->string)) == NULL)
|
||||
environ_clear(dst, ov->string);
|
||||
else
|
||||
environ_set(dst, envent->name, "%s", envent->value);
|
||||
environ_set(dst, envent->name, 0, "%s", envent->value);
|
||||
a = options_array_next(a);
|
||||
}
|
||||
}
|
||||
@ -201,7 +207,9 @@ environ_push(struct environ *env)
|
||||
|
||||
environ = xcalloc(1, sizeof *environ);
|
||||
RB_FOREACH(envent, environ, env) {
|
||||
if (envent->value != NULL && *envent->name != '\0')
|
||||
if (envent->value != NULL &&
|
||||
*envent->name != '\0' &&
|
||||
(~envent->flags & ENVIRON_HIDDEN))
|
||||
setenv(envent->name, envent->value, 1);
|
||||
}
|
||||
}
|
||||
@ -243,14 +251,15 @@ environ_for_session(struct session *s, int no_TERM)
|
||||
|
||||
if (!no_TERM) {
|
||||
value = options_get_string(global_options, "default-terminal");
|
||||
environ_set(env, "TERM", "%s", value);
|
||||
environ_set(env, "TERM", 0, "%s", value);
|
||||
}
|
||||
|
||||
if (s != NULL)
|
||||
idx = s->id;
|
||||
else
|
||||
idx = -1;
|
||||
environ_set(env, "TMUX", "%s,%ld,%d", socket_path, (long)getpid(), idx);
|
||||
environ_set(env, "TMUX", 0, "%s,%ld,%d", socket_path, (long)getpid(),
|
||||
idx);
|
||||
|
||||
return (env);
|
||||
}
|
||||
|
@ -520,6 +520,7 @@ server_client_check_mouse(struct client *c, struct key_event *event)
|
||||
memcpy(&c->click_event, m, sizeof c->click_event);
|
||||
c->click_button = m->b;
|
||||
|
||||
log_debug("click timer started");
|
||||
tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000;
|
||||
tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L;
|
||||
evtimer_del(&c->click_timer);
|
||||
@ -2020,7 +2021,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_IDENTIFY_ENVIRON string");
|
||||
if (strchr(data, '=') != NULL)
|
||||
environ_put(c->environ, data);
|
||||
environ_put(c->environ, data, 0);
|
||||
log_debug("client %p IDENTIFY_ENVIRON %s", c, data);
|
||||
break;
|
||||
case MSG_IDENTIFY_CLIENTPID:
|
||||
|
8
spawn.c
8
spawn.c
@ -303,7 +303,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
child = environ_for_session(s, 0);
|
||||
if (sc->environ != NULL)
|
||||
environ_copy(sc->environ, child);
|
||||
environ_set(child, "TMUX_PANE", "%%%u", new_wp->id);
|
||||
environ_set(child, "TMUX_PANE", 0, "%%%u", new_wp->id);
|
||||
|
||||
/*
|
||||
* Then the PATH environment variable. The session one is replaced from
|
||||
@ -313,10 +313,10 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
if (c != NULL && c->session == NULL) { /* only unattached clients */
|
||||
ee = environ_find(c->environ, "PATH");
|
||||
if (ee != NULL)
|
||||
environ_set(child, "PATH", "%s", ee->value);
|
||||
environ_set(child, "PATH", 0, "%s", ee->value);
|
||||
}
|
||||
if (environ_find(child, "PATH") == NULL)
|
||||
environ_set(child, "%s", _PATH_DEFPATH);
|
||||
environ_set(child, "PATH", 0, "%s", _PATH_DEFPATH);
|
||||
|
||||
/* Then the shell. If respawning, use the old one. */
|
||||
if (~sc->flags & SPAWN_RESPAWN) {
|
||||
@ -326,7 +326,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
free(new_wp->shell);
|
||||
new_wp->shell = xstrdup(tmp);
|
||||
}
|
||||
environ_set(child, "SHELL", "%s", new_wp->shell);
|
||||
environ_set(child, "SHELL", 0, "%s", new_wp->shell);
|
||||
|
||||
/* Log the arguments we are going to use. */
|
||||
log_debug("%s: shell=%s", __func__, new_wp->shell);
|
||||
|
26
tmux.1
26
tmux.1
@ -565,6 +565,18 @@ Environment variables may be set by using the syntax
|
||||
for example
|
||||
.Ql HOME=/home/user .
|
||||
Variables set during parsing are added to the global environment.
|
||||
A hidden variable may be set with
|
||||
.Ql %hidden ,
|
||||
for example:
|
||||
.Bd -literal -offset indent
|
||||
%hidden MYVAR=42
|
||||
.Ed
|
||||
.Pp
|
||||
Hidden variables are not passed to the environment of processes created
|
||||
by tmux.
|
||||
See the
|
||||
.Sx GLOBAL AND SESSION ENVIRONMENT
|
||||
section.
|
||||
.Pp
|
||||
Commands may be parsed conditionally by surrounding them with
|
||||
.Ql %if ,
|
||||
@ -4711,10 +4723,16 @@ from inside, and the
|
||||
variable with the correct terminal setting of
|
||||
.Ql screen .
|
||||
.Pp
|
||||
Variables in both session and global environments may be marked as hidden.
|
||||
Hidden variables are not passed into the environment of new processes and
|
||||
instead can only be used by tmux itself (for example in formats, see the
|
||||
.Sx FORMATS
|
||||
section).
|
||||
.Pp
|
||||
Commands to alter and view the environment are:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo Ic set-environment
|
||||
.Op Fl gru
|
||||
.Op Fl hgru
|
||||
.Op Fl t Ar target-session
|
||||
.Ar name Op Ar value
|
||||
.Xc
|
||||
@ -4731,8 +4749,10 @@ flag unsets a variable.
|
||||
.Fl r
|
||||
indicates the variable is to be removed from the environment before starting a
|
||||
new process.
|
||||
.Fl h
|
||||
marks the variable as hidden.
|
||||
.It Xo Ic show-environment
|
||||
.Op Fl gs
|
||||
.Op Fl hgs
|
||||
.Op Fl t Ar target-session
|
||||
.Op Ar variable
|
||||
.Xc
|
||||
@ -4749,6 +4769,8 @@ Variables removed from the environment are prefixed with
|
||||
If
|
||||
.Fl s
|
||||
is used, the output is formatted as a set of Bourne shell commands.
|
||||
.Fl h
|
||||
shows hidden variables (omitted by default).
|
||||
.El
|
||||
.Sh STATUS LINE
|
||||
.Nm
|
||||
|
4
tmux.c
4
tmux.c
@ -332,9 +332,9 @@ main(int argc, char **argv)
|
||||
|
||||
global_environ = environ_create();
|
||||
for (var = environ; *var != NULL; var++)
|
||||
environ_put(global_environ, *var);
|
||||
environ_put(global_environ, *var, 0);
|
||||
if ((cwd = find_cwd()) != NULL)
|
||||
environ_set(global_environ, "PWD", "%s", cwd);
|
||||
environ_set(global_environ, "PWD", 0, "%s", cwd);
|
||||
|
||||
global_options = options_create(NULL);
|
||||
global_s_options = options_create(NULL);
|
||||
|
9
tmux.h
9
tmux.h
@ -1048,6 +1048,9 @@ struct environ_entry {
|
||||
char *name;
|
||||
char *value;
|
||||
|
||||
int flags;
|
||||
#define ENVIRON_HIDDEN 0x1
|
||||
|
||||
RB_ENTRY(environ_entry) entry;
|
||||
};
|
||||
|
||||
@ -1957,10 +1960,10 @@ 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 printflike(3, 4) environ_set(struct environ *, const char *, const char *,
|
||||
...);
|
||||
void printflike(4, 5) environ_set(struct environ *, const char *, int,
|
||||
const char *, ...);
|
||||
void environ_clear(struct environ *, const char *);
|
||||
void environ_put(struct environ *, const char *);
|
||||
void environ_put(struct environ *, const char *, int);
|
||||
void environ_unset(struct environ *, const char *);
|
||||
void environ_update(struct options *, struct environ *, struct environ *);
|
||||
void environ_push(struct environ *);
|
||||
|
Loading…
Reference in New Issue
Block a user