Removed
Link Here
|
1 |
From: Bruno Haible <bruno@clisp.org> |
2 |
Date: Sat, 23 May 2020 10:19:34 +0000 (+0200) |
3 |
Subject: findprog-in: Ignore directories. |
4 |
X-Git-Url: https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff_plain;h=6e6abd0cdfe4bb96f6412aebc511f10bf254a820 |
5 |
|
6 |
findprog-in: Ignore directories. |
7 |
|
8 |
Reported by Frederick Eaton via Dmitry Goncharov in |
9 |
<https://lists.gnu.org/archive/html/bug-gnulib/2020-03/msg00003.html>. |
10 |
|
11 |
* lib/findprog-in.c (find_in_given_path): When the file found is a |
12 |
directory, set errno to EACCES and, during a PATH search, continue |
13 |
searching. |
14 |
* modules/findprog-in (Depends-on): Add sys_stat, stat. |
15 |
--- |
16 |
|
17 |
diff --git a/lib/findprog-in.c b/lib/findprog-in.c |
18 |
index c254f2f..0f76e36 100644 |
19 |
--- lib/findprog-in.c |
20 |
+++ lib/findprog-in.c |
21 |
@@ -26,6 +26,7 @@ |
22 |
#include <stdlib.h> |
23 |
#include <string.h> |
24 |
#include <unistd.h> |
25 |
+#include <sys/stat.h> |
26 |
|
27 |
#include "filename.h" |
28 |
#include "concat-filename.h" |
29 |
@@ -58,8 +59,8 @@ static const char * const suffixes[] = |
30 |
/* Note: The cmd.exe program does a different lookup: It searches according |
31 |
to the PATHEXT environment variable. |
32 |
See <https://stackoverflow.com/questions/7839150/>. |
33 |
- Also, it executes files ending .bat and .cmd directly without letting the |
34 |
- kernel interpret the program file. */ |
35 |
+ Also, it executes files ending in .bat and .cmd directly without letting |
36 |
+ the kernel interpret the program file. */ |
37 |
#elif defined __CYGWIN__ |
38 |
"", ".exe", ".com" |
39 |
#elif defined __EMX__ |
40 |
@@ -136,14 +137,26 @@ find_in_given_path (const char *progname, const char *path, |
41 |
call access() despite its design flaw. */ |
42 |
if (eaccess (progpathname, X_OK) == 0) |
43 |
{ |
44 |
- /* Found! */ |
45 |
- if (strcmp (progpathname, progname) == 0) |
46 |
+ /* Check that the progpathname does not point to a |
47 |
+ directory. */ |
48 |
+ struct stat statbuf; |
49 |
+ |
50 |
+ if (stat (progpathname, &statbuf) >= 0) |
51 |
{ |
52 |
- free (progpathname); |
53 |
- return progname; |
54 |
+ if (! S_ISDIR (statbuf.st_mode)) |
55 |
+ { |
56 |
+ /* Found! */ |
57 |
+ if (strcmp (progpathname, progname) == 0) |
58 |
+ { |
59 |
+ free (progpathname); |
60 |
+ return progname; |
61 |
+ } |
62 |
+ else |
63 |
+ return progpathname; |
64 |
+ } |
65 |
+ |
66 |
+ errno = EACCES; |
67 |
} |
68 |
- else |
69 |
- return progpathname; |
70 |
} |
71 |
|
72 |
if (errno != ENOENT) |
73 |
@@ -210,25 +223,37 @@ find_in_given_path (const char *progname, const char *path, |
74 |
call access() despite its design flaw. */ |
75 |
if (eaccess (progpathname, X_OK) == 0) |
76 |
{ |
77 |
- /* Found! */ |
78 |
- if (strcmp (progpathname, progname) == 0) |
79 |
+ /* Check that the progpathname does not point to a |
80 |
+ directory. */ |
81 |
+ struct stat statbuf; |
82 |
+ |
83 |
+ if (stat (progpathname, &statbuf) >= 0) |
84 |
{ |
85 |
- free (progpathname); |
86 |
- |
87 |
- /* Add the "./" prefix for real, that |
88 |
- xconcatenated_filename() optimized away. This |
89 |
- avoids a second PATH search when the caller uses |
90 |
- execl/execv/execlp/execvp. */ |
91 |
- progpathname = |
92 |
- XNMALLOC (2 + strlen (progname) + 1, char); |
93 |
- progpathname[0] = '.'; |
94 |
- progpathname[1] = NATIVE_SLASH; |
95 |
- memcpy (progpathname + 2, progname, |
96 |
- strlen (progname) + 1); |
97 |
- } |
98 |
+ if (! S_ISDIR (statbuf.st_mode)) |
99 |
+ { |
100 |
+ /* Found! */ |
101 |
+ if (strcmp (progpathname, progname) == 0) |
102 |
+ { |
103 |
+ free (progpathname); |
104 |
+ |
105 |
+ /* Add the "./" prefix for real, that |
106 |
+ xconcatenated_filename() optimized away. |
107 |
+ This avoids a second PATH search when the |
108 |
+ caller uses execl/execv/execlp/execvp. */ |
109 |
+ progpathname = |
110 |
+ XNMALLOC (2 + strlen (progname) + 1, char); |
111 |
+ progpathname[0] = '.'; |
112 |
+ progpathname[1] = NATIVE_SLASH; |
113 |
+ memcpy (progpathname + 2, progname, |
114 |
+ strlen (progname) + 1); |
115 |
+ } |
116 |
+ |
117 |
+ free (path_copy); |
118 |
+ return progpathname; |
119 |
+ } |
120 |
|
121 |
- free (path_copy); |
122 |
- return progpathname; |
123 |
+ errno = EACCES; |
124 |
+ } |
125 |
} |
126 |
|
127 |
if (errno != ENOENT) |