[PATCH] exec: Print absolute paths for command location queries
Kerin Millar <[email protected]> Sat, 6 Jun 2026 16:36:34 +0100
| Newsgroups | org.kernel.vger.dash |
|---|---|
| Message-ID | <[email protected]> |
POSIX requires that, when reporting the location of a utility found by
searching PATH (or one named with a slash), the pathname written by
type, command -v and command -V be absolute:
Executable utilities, regular built-in utilities, command_names
including a <slash> character, and any implementation-provided
functions that are found using the PATH variable [...] shall be
written as absolute pathnames.
Presently, dash fails to conform in this regard. Address this issue by
incorporating a helper function that prefixes relative pathnames with
the shell's cached current working directory.
Link: https://lore.kernel.org/dash/[email protected]/
Reported-by: Christoph Anton Mitterer <[email protected]>
Signed-off-by: Kerin Millar <[email protected]>
---
src/cd.c | 11 +++++++++++
src/cd.h | 1 +
src/exec.c | 26 ++++++++++++++++++++++----
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/src/cd.c b/src/cd.c
index bcd1484..c044c3f 100644
--- a/src/cd.c
+++ b/src/cd.c
@@ -330,3 +330,14 @@ setpwd(const char *val, int setold)
INTON;
setvar("PWD", dir, VEXPORT);
}
+
+/*
+ * Return the shell's notion of the current working directory. Unlike the PWD
+ * variable, this cannot be altered by the user.
+ */
+
+const char *
+curpwd(void)
+{
+ return curdir;
+}
diff --git a/src/cd.h b/src/cd.h
index 8763161..2457e9c 100644
--- a/src/cd.h
+++ b/src/cd.h
@@ -33,3 +33,4 @@
int cdcmd(int, char **);
int pwdcmd(int, char **);
void setpwd(const char *, int);
+const char *curpwd(void);
diff --git a/src/exec.c b/src/exec.c
index 6fe0fed..006a241 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -58,6 +58,7 @@
#include "redir.h"
#include "eval.h"
#include "exec.h"
+#include "cd.h"
#include "builtins.h"
#include "var.h"
#include "options.h"
@@ -779,6 +780,24 @@ typecmd(int argc, char **argv)
return err;
}
+/*
+ * Print the location of a command, as reported by type, command -v and
+ * command -V. POSIX requires such pathnames to be absolute.
+ */
+
+static void printpath(struct output *out, const char *p)
+{
+ const char *pwd;
+
+ if (*p != '/' && *(pwd = curpwd()) == '/') {
+ outstr(pwd, out);
+ /* Do not append another slash to / or //. */
+ if (pwd[strlen(pwd) - 1] != '/')
+ outc('/', out);
+ }
+ outstr(p, out);
+}
+
static int describe_command(struct output *out, char *command,
const char *path, int verbose)
{
@@ -840,12 +859,11 @@ static int describe_command(struct output *out, char *command,
}
if (verbose) {
outfmt(
- out, " is%s %s",
- cmdp ? " a tracked alias for" : nullstr, p
+ out, " is%s ",
+ cmdp ? " a tracked alias for" : nullstr
);
- } else {
- outstr(p, out);
}
+ printpath(out, p);
break;
}
--
2.53.0