summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2020-03-31 17:14:40 +0000
committernicm <nicm>2020-03-31 17:14:40 +0000
commitcc8b41f294974cdfb1ddfe3b907da58374ff130f (patch)
tree32855ba0999368039d3d7d40ecbbec3c096c50f9
parente6cddcf752b335cb945bba4619b500b527cfee0a (diff)
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.
-rw-r--r--cmd-new-window.c2
-rw-r--r--cmd-parse.y23
-rw-r--r--cmd-respawn-pane.c2
-rw-r--r--cmd-respawn-window.c2
-rw-r--r--cmd-set-environment.c9
-rw-r--r--cmd-show-environment.c12
-rw-r--r--cmd-split-window.c2
-rw-r--r--environ.c29
-rw-r--r--server-client.c3
-rw-r--r--spawn.c8
-rw-r--r--tmux.126
-rw-r--r--tmux.c4
-rw-r--r--tmux.h9
13 files changed, 98 insertions, 33 deletions
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 9a1025e9..a4d6c014 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -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);
}
diff --git a/cmd-parse.y b/cmd-parse.y
index 2375370b..aabfe2d3 100644
--- a/cmd-parse.y
+++ b/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
@@ -138,6 +139,11 @@ statement : /* empty */
$$ = xmalloc (sizeof *$$);
TAILQ_INIT($$);
}
+ | hidden_assignment
+ {
+ $$ = xmalloc (sizeof *$$);
+ TAILQ_INIT($$);
+ }
| condition
{
struct cmd_parse_state *ps = &parse_state;
@@ -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);
diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c
index 5e23fa15..55544f93 100644
--- a/cmd-respawn-pane.c
+++ b/cmd-respawn-pane.c
@@ -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);
}
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index 497e401e..5f44db12 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -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);
}
diff --git a/cmd-set-environment.c b/cmd-set-environment.c
index a80acd01..248f734a 100644
--- a/cmd-set-environment.c
+++ b/cmd-set-environment.c
@@ -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);
diff --git a/cmd-show-environment.c b/cmd-show-environment.c
index eb19cf20..0d2f7dd9 100644
--- a/cmd-show-environment.c
+++ b/cmd-show-environment.c
@@ -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)
diff --git a/cmd-split-window.c b/cmd-split-window.c
index e8c2050e..c1c8be25 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -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);
}
diff --git a/environ.c b/environ.c
index 25968f7b..0ce717df 100644
--- a/environ.c
+++ b/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);
}
diff --git a/server-client.c b/server-client.c
index aa174d4d..054e1161 100644
--- a/server-client.c
+++ b/server-client.c
@@ -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:
diff --git a/spawn.c b/spawn.c
index 45243517..865a77e2 100644
--- a/spawn.c
+++ b/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);
diff --git a/tmux.1 b/tmux.1
index b0fc5600..e785cf8b 100644
--- a/tmux.1
+++ b/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
diff --git a/tmux.c b/tmux.c
index 60b35e5d..2055a894 100644
--- a/tmux.c
+++ b/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);
diff --git a/tmux.h b/tmux.h
index 20559144..53bbc222 100644
--- a/tmux.h
+++ b/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 *);