Set PWD so shells have a hint about the real path (this was done before
authornicm <nicm@openbsd.org>
Mon, 30 May 2022 13:06:41 +0000 (13:06 +0000)
committernicm <nicm@openbsd.org>
Mon, 30 May 2022 13:06:41 +0000 (13:06 +0000)
but lost in a merge). GitHub issue 3186.

usr.bin/tmux/spawn.c

index 4cde347..1d8c96b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: spawn.c,v 1.29 2021/08/23 11:04:21 nicm Exp $ */
+/* $OpenBSD: spawn.c,v 1.30 2022/05/30 13:06:41 nicm Exp $ */
 
 /*
  * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -211,7 +211,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
        struct window_pane       *new_wp;
        struct environ           *child;
        struct environ_entry     *ee;
-       char                    **argv, *cp, **argvp, *argv0, *cwd;
+       char                    **argv, *cp, **argvp, *argv0, *cwd, *new_cwd;
        const char               *cmd, *tmp;
        int                       argc;
        u_int                     idx;
@@ -227,9 +227,15 @@ spawn_pane(struct spawn_context *sc, char **cause)
         * Work out the current working directory. If respawning, use
         * the pane's stored one unless specified.
         */
-       if (sc->cwd != NULL)
+       if (sc->cwd != NULL) {
                cwd = format_single(item, sc->cwd, c, target->s, NULL, NULL);
-       else if (~sc->flags & SPAWN_RESPAWN)
+               if (*cwd != '/') {
+                       xasprintf(&new_cwd, "%s/%s", server_client_get_cwd(c,
+                           target->s), cwd);
+                       free(cwd);
+                       cwd = new_cwd;
+               }
+       } else if (~sc->flags & SPAWN_RESPAWN)
                cwd = xstrdup(server_client_get_cwd(c, target->s));
        else
                cwd = NULL;
@@ -337,8 +343,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
                log_debug("%s: cmd=%s", __func__, cp);
                free(cp);
        }
-       if (cwd != NULL)
-               log_debug("%s: cwd=%s", __func__, cwd);
+       log_debug("%s: cwd=%s", __func__, new_wp->cwd);
        cmd_log_argv(new_wp->argc, new_wp->argv, "%s", __func__);
        environ_log(child, "%s: environment ", __func__);
 
@@ -384,9 +389,13 @@ spawn_pane(struct spawn_context *sc, char **cause)
         * Child process. Change to the working directory or home if that
         * fails.
         */
-       if (chdir(new_wp->cwd) != 0 &&
-           ((tmp = find_home()) == NULL || chdir(tmp) != 0) &&
-           chdir("/") != 0)
+       if (chdir(new_wp->cwd) == 0)
+               environ_set(child, "PWD", 0, "%s", new_wp->cwd);
+       else if ((tmp = find_home()) != NULL || chdir(tmp) == 0)
+               environ_set(child, "PWD", 0, "%s", tmp);
+       else if (chdir("/") == 0)
+               environ_set(child, "PWD", 0, "/");
+       else
                fatal("chdir failed");
 
        /*