diff options
| author | user <user@clank> | 2026-08-14 22:06:27 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-14 22:06:27 +0200 |
| commit | 360ee83a9bae4d06db1ab7747ef984cd7292883d (patch) | |
| tree | df0c65da1753f288d875483538b3f6517628d289 /src/path.c | |
| parent | sl0ppty: walk the row, not screen_at() (diff) | |
| download | slosh-360ee83a9bae4d06db1ab7747ef984cd7292883d.tar.gz slosh-360ee83a9bae4d06db1ab7747ef984cd7292883d.tar.xz slosh-360ee83a9bae4d06db1ab7747ef984cd7292883d.zip | |
sl0ppty: expand ~ in a path that a config file wrote
`cwd="~/dev/api"` is in the README, in config/layout.example.kdl, and did
nothing. `~` is a shell thing, and no shell has touched a path that arrives
from a layout file -- so it went to chdir() literally, failed, and left the
pane in whatever directory the session happened to be started from. The pane
still ran, so nothing looked wrong until you typed `ls`.
path_expand() handles `~` and `~/...` against $HOME and returns everything
else untouched, including `~user`, which needs the password database and is
not worth linking it in for -- returned unchanged rather than half-expanded
into something wrong.
Applied where a layout's cwd is read, which is one place because a pane
inherits its tab's. Found while documenting a shader directory that was
about to have exactly the same bug.
Diffstat (limited to 'src/path.c')
| -rw-r--r-- | src/path.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/path.c b/src/path.c new file mode 100644 index 0000000..adf824b --- /dev/null +++ b/src/path.c @@ -0,0 +1,25 @@ +/* Paths as people write them. + * + * `~` is a shell thing: by the time a path reaches us from a config or layout + * file no shell has touched it, so `cwd="~/dev/api"` was being handed to + * chdir() literally, failing, and leaving the pane in whatever directory the + * session happened to be in. Silently \u2014 which is the worst way for a path to + * be wrong, because the pane still starts and still works. + */ +#include "sl0ppty.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +const char *path_expand(const char *path, char *buf, size_t cap) { + if (!path) return NULL; + /* `~` and `~/...` only. `~user` needs the password database and is not + * worth linking it in for; it is returned unchanged, which is exactly what + * it did before, rather than being half-expanded into something wrong. */ + if (path[0] != '~' || (path[1] && path[1] != '/')) return path; + const char *home = getenv("HOME"); + if (!home || !*home) return path; + snprintf(buf, cap, "%s%s", home, path + 1); + return buf; +} |
