Just found a problem: sourcing the tmux configuration expands the environment variables, too, and I don't see any way that allows escaping. That means ':new-window -c "$PWD"' on the prompt works but binding the same will resolve $PWD when parsing the config, not when pressing the keys. Any recommendations how to solve this?
Did one of those "small cosmetic changes" in the last minute and missed to remove the & in environ_find(&environ, ...). The attached patch fixes that. --- cfg.c | 2 +- cmd-command-prompt.c | 3 ++- cmd-confirm-before.c | 3 ++- cmd-if-shell.c | 3 ++- cmd-string.c | 38 +++++++++++++++++++++++--------------- control.c | 3 ++- tmux.h | 4 ++-- window-choose.c | 3 ++- 8 files changed, 36 insertions(+), 23 deletions(-) diff --git a/cfg.c b/cfg.c index 1153de6..34a49e2 100644 --- a/cfg.c +++ b/cfg.c @@ -91,7 +91,7 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause) } /* Parse and run the command. */ - if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) { + if (cmd_string_parse(NULL, buf, &cmdlist, path, n, &cause1) != 0) { free(copy); if (cause1 == NULL) continue; diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 759d578..8c1393c 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -172,7 +172,8 @@ cmd_command_prompt_callback(void *data, const char *s) return (1); } - if (cmd_string_parse(new_template, &cmdlist, NULL, 0, &cause) != 0) { + if (cmd_string_parse(&c->session->environ, new_template, &cmdlist, + NULL, 0, &cause) != 0) { if (cause != NULL) { *cause = toupper((u_char) *cause); status_message_set(c, "%s", cause); diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index 9266721..691810f 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -115,7 +115,8 @@ cmd_confirm_before_callback(void *data, const char *s) if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') return (0); - if (cmd_string_parse(cdata->cmd, &cmdlist, NULL, 0, &cause) != 0) { + if (cmd_string_parse(&c->session->environ, cdata->cmd, &cmdlist, NULL, + 0, &cause) != 0) { if (cause != NULL) { cmdq_error(c->cmdq, "%s", cause); free(cause); diff --git a/cmd-if-shell.c b/cmd-if-shell.c index 9b6dcf3..e79c0c4 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -123,7 +123,8 @@ cmd_if_shell_callback(struct job *job) if (cmd == NULL) return; - if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) { + if (cmd_string_parse(&cmdq->client->session->environ, cmd, &cmdlist, + NULL, 0, &cause) != 0) { if (cause != NULL) { cmdq_error(cmdq, "%s", cause); free(cause); diff --git a/cmd-string.c b/cmd-string.c index e793ea0..77dc8af 100644 --- a/cmd-string.c +++ b/cmd-string.c @@ -34,9 +34,9 @@ int cmd_string_getc(const char *, size_t *); void cmd_string_ungetc(size_t *); void cmd_string_copy(char **, char *, size_t *); -char *cmd_string_string(const char *, size_t *, char, int); -char *cmd_string_variable(const char *, size_t *); -char *cmd_string_expand_tilde(const char *, size_t *); +char *cmd_string_string(struct environ *, const char *, size_t *, char, int); +char *cmd_string_variable(struct environ *, const char *, size_t *); +char *cmd_string_expand_tilde(struct environ *, const char *, size_t *); int cmd_string_getc(const char *s, size_t *p) @@ -59,8 +59,8 @@ cmd_string_ungetc(size_t *p) * string, or NULL for empty command. */ int -cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file, - u_int line, char **cause) +cmd_string_parse(struct environ* environ, const char *s, + struct cmd_list **cmdlist, const char *file, u_int line, char **cause) { size_t p; int ch, i, argc, rval; @@ -84,17 +84,17 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file, ch = cmd_string_getc(s, &p); switch (ch) { case '\'': - if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL) + if ((t = cmd_string_string(environ, s, &p, '\'', 0)) == NULL) goto error; cmd_string_copy(&buf, t, &len); break; case '"': - if ((t = cmd_string_string(s, &p, '"', 1)) == NULL) + if ((t = cmd_string_string(environ, s, &p, '"', 1)) == NULL) goto error; cmd_string_copy(&buf, t, &len); break; case '$': - if ((t = cmd_string_variable(s, &p)) == NULL) + if ((t = cmd_string_variable(environ, s, &p)) == NULL) goto error; cmd_string_copy(&buf, t, &len); break; @@ -140,7 +140,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file, goto out; case '~': if (buf == NULL) { - t = cmd_string_expand_tilde(s, &p); + t = cmd_string_expand_tilde(environ, s, &p); if (t == NULL) goto error; cmd_string_copy(&buf, t, &len); @@ -187,7 +187,7 @@ cmd_string_copy(char **dst, char *src, size_t *len) } char * -cmd_string_string(const char *s, size_t *p, char endch, int esc) +cmd_string_string(struct environ *environ, const char *s, size_t *p, char endch, int esc) { int ch; char *buf, *t; @@ -223,7 +223,7 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc) case '$': if (!esc) break; - if ((t = cmd_string_variable(s, p)) == NULL) + if ((t = cmd_string_variable(environ, s, p)) == NULL) goto error; cmd_string_copy(&buf, t, &len); continue; @@ -245,7 +245,7 @@ error: } char * -cmd_string_variable(const char *s, size_t *p) +cmd_string_variable(struct environ *environ, const char *s, size_t *p) { int ch, fch; char *buf, *t; @@ -302,7 +302,11 @@ cmd_string_variable(const char *s, size_t *p) buf = xrealloc(buf, 1, len + 1); buf[len] = '\0'; - envent = environ_find(&global_environ, buf); + envent = NULL; + if (environ) + envent = environ_find(environ, buf); + if (envent == NULL) + envent = environ_find(&global_environ, buf); free(buf); if (envent == NULL) return (xstrdup("")); @@ -314,7 +318,7 @@ error: } char * -cmd_string_expand_tilde(const char *s, size_t *p) +cmd_string_expand_tilde(struct environ *environ, const char *s, size_t *p) { struct passwd *pw; struct environ_entry *envent; @@ -325,7 +329,11 @@ cmd_string_expand_tilde(const char *s, size_t *p) last = cmd_string_getc(s, p); if (last == EOF || last == '/' || last == ' '|| last == '\t') { - envent = environ_find(&global_environ, "HOME"); + envent = NULL; + if (environ) + envent = environ_find(environ, "HOME"); + if (envent == NULL) + envent = environ_find(&global_environ, "HOME"); if (envent != NULL && *envent->value != '\0') home = envent->value; else if ((pw = getpwuid(getuid())) != NULL) diff --git a/control.c b/control.c index 52fdb52..4b5df7b 100644 --- a/control.c +++ b/control.c @@ -69,7 +69,8 @@ control_callback(struct client *c, int closed, unused void *data) break; } - if (cmd_string_parse(line, &cmdlist, NULL, 0, &cause) != 0) { + if (cmd_string_parse(&c->session->environ, line, &cmdlist, + NULL, 0, &cause) != 0) { c->cmdq->time = time(NULL); c->cmdq->number++; diff --git a/tmux.h b/tmux.h index 84ad164..deff813 100644 --- a/tmux.h +++ b/tmux.h @@ -1841,8 +1841,8 @@ int cmdq_continue(struct cmd_q *); void cmdq_flush(struct cmd_q *); /* cmd-string.c */ -int cmd_string_parse(const char *, struct cmd_list **, const char *, - u_int, char **); +int cmd_string_parse(struct environ *, const char *, struct cmd_list **, + const char *, u_int, char **); /* client.c */ int client_main(int, char **, int); diff --git a/window-choose.c b/window-choose.c index 572581a..bc10b7e 100644 --- a/window-choose.c +++ b/window-choose.c @@ -228,7 +228,8 @@ window_choose_data_run(struct window_choose_data *cdata) if (cdata->command == NULL) return; - if (cmd_string_parse(cdata->command, &cmdlist, NULL, 0, &cause) != 0) { + if (cmd_string_parse(&cdata->start_session->environ, cdata->command, + &cmdlist, NULL, 0, &cause) != 0) { if (cause != NULL) { *cause = toupper((u_char) *cause); status_message_set(cdata->start_client, "%s", cause); -- 1.7.10.4 ------------------------------------------------------------------------------ Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users