]> Savannah Git Hosting - gnulib.git/commitdiff
findprog-in: Ignore directories.
authorBruno Haible <bruno@clisp.org>
Sat, 23 May 2020 10:19:34 +0000 (12:19 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 23 May 2020 17:40:26 +0000 (19:40 +0200)
Reported by Frederick Eaton via Dmitry Goncharov in
<https://lists.gnu.org/archive/html/bug-gnulib/2020-03/msg00003.html>.

* lib/findprog-in.c (find_in_given_path): When the file found is a
directory, set errno to EACCES and, during a PATH search, continue
searching.
* modules/findprog-in (Depends-on): Add sys_stat, stat.

ChangeLog
lib/findprog-in.c
modules/findprog-in

index 44450a3549b0b63386aa896ea903cbba16a172af..b22d791c60e5e9e33e150c91d1d9397b46c18f4a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2020-05-23  Bruno Haible  <bruno@clisp.org>
+
+       findprog-in: Ignore directories.
+       Reported by Frederick Eaton via Dmitry Goncharov in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2020-03/msg00003.html>.
+       * lib/findprog-in.c (find_in_given_path): When the file found is a
+       directory, set errno to EACCES and, during a PATH search, continue
+       searching.
+       * modules/findprog-in (Depends-on): Add sys_stat, stat.
+
 2020-05-23  Paul Eggert  <eggert@cs.ucla.edu>
 
        verify: document ‘assume’ better
index c254f2f588eaad0db9734724ed98b6daf627a74a..0f76e36ca43ea1ae05d07df0cfdacff69877d571 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/stat.h>
 
 #include "filename.h"
 #include "concat-filename.h"
@@ -58,8 +59,8 @@ static const char * const suffixes[] =
     /* Note: The cmd.exe program does a different lookup: It searches according
        to the PATHEXT environment variable.
        See <https://stackoverflow.com/questions/7839150/>.
-       Also, it executes files ending .bat and .cmd directly without letting the
-       kernel interpret the program file.  */
+       Also, it executes files ending in .bat and .cmd directly without letting
+       the kernel interpret the program file.  */
     #elif defined __CYGWIN__
     "", ".exe", ".com"
     #elif defined __EMX__
@@ -136,14 +137,26 @@ find_in_given_path (const char *progname, const char *path,
                        call access() despite its 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)
                           {
-                            free (progpathname);
-                            return progname;
+                            if (! S_ISDIR (statbuf.st_mode))
+                              {
+                                /* Found!  */
+                                if (strcmp (progpathname, progname) == 0)
+                                  {
+                                    free (progpathname);
+                                    return progname;
+                                  }
+                                else
+                                  return progpathname;
+                              }
+
+                            errno = EACCES;
                           }
-                        else
-                          return progpathname;
                       }
 
                     if (errno != ENOENT)
@@ -210,25 +223,37 @@ find_in_given_path (const char *progname, const char *path,
                    call access() despite its 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)
                       {
-                        free (progpathname);
-
-                        /* Add the "./" prefix for real, that
-                           xconcatenated_filename() optimized away.  This
-                           avoids a second PATH search when the caller uses
-                           execl/execv/execlp/execvp.  */
-                        progpathname =
-                          XNMALLOC (2 + strlen (progname) + 1, char);
-                        progpathname[0] = '.';
-                        progpathname[1] = NATIVE_SLASH;
-                        memcpy (progpathname + 2, progname,
-                                strlen (progname) + 1);
-                      }
+                        if (! S_ISDIR (statbuf.st_mode))
+                          {
+                            /* 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 execl/execv/execlp/execvp.  */
+                                progpathname =
+                                  XNMALLOC (2 + strlen (progname) + 1, char);
+                                progpathname[0] = '.';
+                                progpathname[1] = NATIVE_SLASH;
+                                memcpy (progpathname + 2, progname,
+                                        strlen (progname) + 1);
+                              }
+
+                            free (path_copy);
+                            return progpathname;
+                          }
 
-                    free (path_copy);
-                    return progpathname;
+                        errno = EACCES;
+                      }
                   }
 
                 if (errno != ENOENT)
index 971366b83ad310d446f6dec9460d1b65f1a42146..84787a644e620f90f59c7a4d57c63d28b23762da 100644 (file)
@@ -9,10 +9,12 @@ m4/eaccess.m4
 
 Depends-on:
 stdbool
+sys_stat
 filename
 xalloc
 xconcat-filename
 access
+stat
 unistd
 
 configure.ac: