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

Reply via email to