Elliot Hughes wrote: > yeah, _PATH_DEFPATH is the only path string we offer anyway, but it should > be reasonable for this kind of use case.
Thanks. I'm using it now, in the patch below. > > And which binaries exist in /bin = /system/bin ? > > "all the usual unix stuff [that we have]". the other stuff is probably a > mistake, but nothing i cared enough about to fight. Thanks for the info. Indeed, some of the binaries work (such as /bin/sh, /bin/ls), while others don't: $ /bin/df /bin/df: 1: Syntax error: word unexpected (expecting ")") Probably this doesn't get reported, because people don't know about these binaries :) Bruno 2026-11-03 Bruno Haible <[email protected]> findprog*: Don't use the empty PATH as fallback on most platforms. Reported by Pádraig Brady in <https://lists.gnu.org/archive/html/bug-gnulib/2026-11/msg00010.html>. * lib/findprog.c: Include <paths.h>. (find_in_path): If confstr fails, just abort. On Android, use _PATH_DEFPATH, as recommended by Elliott Hughes. * lib/findprog-in.c: Include <paths.h>. (find_in_given_path): If confstr fails, just abort. On Android, use _PATH_DEFPATH, as recommended by Elliott Hughes. diff --git a/lib/findprog-in.c b/lib/findprog-in.c index d937f7c834..24cd2f9014 100644 --- a/lib/findprog-in.c +++ b/lib/findprog-in.c @@ -26,6 +26,9 @@ #include <string.h> #include <unistd.h> #include <sys/stat.h> +#ifdef __ANDROID__ +# include <paths.h> +#endif #include "filename.h" #include "concat-filename.h" @@ -223,10 +226,18 @@ find_in_given_path (const char *progname, const char *path, dependent. On POSIX systems, it is confstr (_CS_PATH). */ #if HAVE_CONFSTR int ret = confstr (_CS_PATH, default_path, sizeof (default_path)); - if (ret == 0 || ret > sizeof (default_path)) - #endif - default_path[0] = '\0'; + if (ret == 0) + /* The platform has confstr(), but it does not support _CS_PATH. */ + abort (); + if (ret > sizeof (default_path)) + /* MAX_DEFAULT_PATH_SIZE is too small. Increase it. */ + abort (); path = default_path; + #elif defined __ANDROID__ + path = _PATH_DEFPATH; + #else /* native Windows, Minix */ + path = ""; + #endif } { diff --git a/lib/findprog.c b/lib/findprog.c index 2d321dc0d9..2a017e8686 100644 --- a/lib/findprog.c +++ b/lib/findprog.c @@ -27,6 +27,9 @@ #if !(defined _WIN32 || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__) # include <sys/stat.h> #endif +#ifdef __ANDROID__ +# include <paths.h> +#endif /* Avoid collision between findprog.c and findprog-lgpl.c. */ #if IN_FINDPROG_LGPL || ! GNULIB_FINDPROG_LGPL @@ -69,7 +72,7 @@ find_in_path (const char *progname) the current directory. PATH is not used. */ return progname; - char *path = getenv ("PATH"); + const char *path = getenv ("PATH"); char default_path[MAX_DEFAULT_PATH_SIZE]; if (path == NULL) { @@ -77,24 +80,33 @@ find_in_path (const char *progname) dependent. On POSIX systems, it is confstr (_CS_PATH). */ #if HAVE_CONFSTR int ret = confstr (_CS_PATH, default_path, sizeof (default_path)); - if (ret == 0 || ret > sizeof (default_path)) - #endif - default_path[0] = '\0'; + if (ret == 0) + /* The platform has confstr(), but it does not support _CS_PATH. */ + abort (); + if (ret > sizeof (default_path)) + /* MAX_DEFAULT_PATH_SIZE is too small. Increase it. */ + abort (); path = default_path; + #elif defined __ANDROID__ + path = _PATH_DEFPATH; + #else /* native Windows, Minix */ + path = ""; + #endif } if (*path == '\0') return progname; /* Make a copy, to prepare for destructive modifications. */ + char *path_copy; # if !IN_FINDPROG_LGPL - path = xstrdup (path); + path_copy = xstrdup (path); # else - path = strdup (path); - if (path == NULL) + path_copy = strdup (path); + if (path_copy == NULL) /* Out of memory. */ return progname; # endif - for (char *path_rest = path; ; ) + for (char *path_rest = path_copy; ; ) { /* Extract next directory in PATH. */ const char *dir = path_rest; @@ -117,7 +129,7 @@ find_in_path (const char *progname) if (progpathname == NULL) { /* Out of memory. */ - free (path); + free (path_copy); return progname; } # endif @@ -149,7 +161,7 @@ find_in_path (const char *progname) if (progpathname == NULL) { /* Out of memory. */ - free (path); + free (path_copy); return progname; } # endif @@ -158,7 +170,7 @@ find_in_path (const char *progname) memcpy (progpathname + 2, progname, strlen (progname) + 1); } - free (path); + free (path_copy); return progpathname; } } @@ -172,7 +184,7 @@ find_in_path (const char *progname) } /* Not found in PATH. An error will be signalled at the first call. */ - free (path); + free (path_copy); return progname; #endif }
