diff options
author | nicm <nicm> | 2020-03-31 17:14:40 +0000 |
---|---|---|
committer | nicm <nicm> | 2020-03-31 17:14:40 +0000 |
commit | cc8b41f294974cdfb1ddfe3b907da58374ff130f (patch) | |
tree | 32855ba0999368039d3d7d40ecbbec3c096c50f9 | |
parent | e6cddcf752b335cb945bba4619b500b527cfee0a (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.c | 2 | ||||
-rw-r--r-- | cmd-parse.y | 23 | ||||
-rw-r--r-- | cmd-respawn-pane.c | 2 | ||||
-rw-r--r-- | cmd-respawn-window.c | 2 | ||||
-rw-r--r-- | cmd-set-environment.c | 9 | ||||
-rw-r--r-- | cmd-show-environment.c | 12 | ||||
-rw-r--r-- | cmd-split-window.c | 2 | ||||
-rw-r--r-- | environ.c | 29 | ||||
-rw-r--r-- | server-client.c | 3 | ||||
-rw-r--r-- | spawn.c | 8 | ||||
-rw-r--r-- | tmux.1 | 26 | ||||
-rw-r--r-- | tmux.c | 4 | ||||
-rw-r--r-- | tmux.h | 9 |
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); } @@ -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: @@ -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); @@ -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 @@ -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); @@ -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 *); |