From 122b6c17349667f6b7080a9db81638eaa2967ccb Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Sun, 24 Jul 2022 14:29:20 +0200 Subject: [PATCH] status: Only realpath if we got an absolute path Otherwise realpath would add the cwd, which would be broken if fish ever cd'd. We could add the original cwd, but even that isn't enough, because we need *the parent's* idea of cwd and $PATH. Or, alternatively, what we need is for the OS to give us the actual path to ourselves. --- src/builtins/status.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/builtins/status.cpp b/src/builtins/status.cpp index d4a1e70d2..4b98cd826 100644 --- a/src/builtins/status.cpp +++ b/src/builtins/status.cpp @@ -455,12 +455,30 @@ maybe_t builtin_status(parser_t &parser, io_streams_t &streams, const wchar } case STATUS_FISH_PATH: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd); - auto real = wrealpath(str2wcstring(get_executable_path("fish"))); - if (real) { - streams.out.append(*real); - streams.out.push_back(L'\n'); + auto path = str2wcstring(get_executable_path("fish")); + if (path.empty()) { + streams.err.append_format(L"%ls: Could not get executable path: '%s'\n", cmd, std::strerror(errno)); + break; + } + + if (path[0] == L'/') { + // This is an absolute path, we can canonicalize it. + auto real = wrealpath(path); + if (real && waccess(*real, F_OK)) { + streams.out.append(*real); + streams.out.push_back(L'\n'); + } else { + // realpath did not work, just append the path + // - maybe this was obtained via $PATH? + streams.out.append(path); + streams.out.push_back(L'\n'); + } } else { - streams.err.append_format(L"%ls: realpath failed: '%s'\n", cmd, std::strerror(errno)); + // This is a relative path, it depends on where fish's parent process + // was when it started it and its idea of $PATH. + // The best we can do is to print it directly and hope it works. + streams.out.append(path); + streams.out.push_back(L'\n'); } break; }