]> Savannah Git Hosting - gnulib.git/commitdiff
findprog, relocatable-prog: Ignore directories during PATH search.
authorBruno Haible <bruno@clisp.org>
Sat, 7 Mar 2020 18:56:33 +0000 (19:56 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 7 Mar 2020 18:56:33 +0000 (19:56 +0100)
Reported by Frederick Eaton via Dmitry Goncharov in
<https://lists.gnu.org/archive/html/bug-gnulib/2020-03/msg00003.html>.

* lib/findprog.c (find_in_path): When the file found in a PATH element
is a directory, continue searching.
* lib/progreloc.c (maybe_executable): Likewise.

ChangeLog
lib/findprog.c
lib/progreloc.c

index 8414234c0e9c800944309235c1172ef7ad937b7b..0eddfee99d9212bc73457b3f309c657df3c359cb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2020-03-07  Bruno Haible  <bruno@clisp.org>
+
+       findprog, relocatable-prog: Ignore directories during PATH search.
+       Reported by Frederick Eaton via Dmitry Goncharov in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2020-03/msg00003.html>.
+       * lib/findprog.c (find_in_path): When the file found in a PATH element
+       is a directory, continue searching.
+       * lib/progreloc.c (maybe_executable): Likewise.
+
 2020-03-07  Bruno Haible  <bruno@clisp.org>
 
        openat: Fix theoretically possible issue on GNU/Hurd.
index d0d41791e22fb3e0755241e56c213a7c5614b040..d834301bd76ba77c70470d4ad8ac566136cccd88 100644 (file)
@@ -105,22 +105,29 @@ find_in_path (const char *progname)
          design flaw.  */
       if (eaccess (progpathname, X_OK) == 0)
         {
-          /* Found!  */
-          if (strcmp (progpathname, progname) == 0)
+          /* Check that the progpathname does not point to a directory.  */
+          struct stat statbuf;
+
+          if (stat (progpathname, &statbuf) >= 0
+              && ! S_ISDIR (statbuf.st_mode))
             {
-              free (progpathname);
-
-              /* Add the "./" prefix for real, that xconcatenated_filename()
-                 optimized away.  This avoids a second PATH search when the
-                 caller uses execlp/execvp.  */
-              progpathname = XNMALLOC (2 + strlen (progname) + 1, char);
-              progpathname[0] = '.';
-              progpathname[1] = '/';
-              memcpy (progpathname + 2, progname, strlen (progname) + 1);
+              /* Found!  */
+              if (strcmp (progpathname, progname) == 0)
+                {
+                  free (progpathname);
+
+                  /* Add the "./" prefix for real, that xconcatenated_filename()
+                     optimized away.  This avoids a second PATH search when the
+                     caller uses execlp/execvp.  */
+                  progpathname = XNMALLOC (2 + strlen (progname) + 1, char);
+                  progpathname[0] = '.';
+                  progpathname[1] = '/';
+                  memcpy (progpathname + 2, progname, strlen (progname) + 1);
+                }
+
+              free (path);
+              return progpathname;
             }
-
-          free (path);
-          return progpathname;
         }
 
       free (progpathname);
index 2acf3fb33fd16fb7a2b8343fc7a6f88bc00cb908..04cef323f344d341b10016e740b79550eea484d9 100644 (file)
@@ -154,7 +154,7 @@ static int executable_fd = -1;
 /* Define this function only when it's needed.  */
 #if !(defined WINDOWS_NATIVE || defined __EMX__)
 
-/* Tests whether a given pathname may belong to the executable.  */
+/* Tests whether a given filename may belong to the executable.  */
 static bool
 maybe_executable (const char *filename)
 {
@@ -173,18 +173,20 @@ maybe_executable (const char *filename)
       struct stat statfile;
 
       if (fstat (executable_fd, &statexe) >= 0)
-        {
-          if (stat (filename, &statfile) < 0)
-            return false;
-          if (!(statfile.st_dev
+        return (stat (filename, &statfile) >= 0
+                && statfile.st_dev
                 && statfile.st_dev == statexe.st_dev
-                && statfile.st_ino == statexe.st_ino))
-            return false;
-        }
+                && statfile.st_ino == statexe.st_ino);
     }
 # endif
 
-  return true;
+  /* Check that the filename does not point to a directory.  */
+  {
+    struct stat statfile;
+
+    return (stat (filename, &statfile) >= 0
+            && ! S_ISDIR (statfile.st_mode));
+  }
 }
 
 #endif