aboutsummaryrefslogtreecommitdiff
path: root/libbb/execable.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-05-02 17:08:29 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-05-02 17:08:29 +0200
commit15a357e5962634c94ee322fee4da897312090a89 (patch)
tree757286a47b38c0c405ab0c5b9aa82a0c87c3a22d /libbb/execable.c
parenta4476eb6543505f8685b59b138cb868b32347d71 (diff)
downloadbusybox-15a357e5962634c94ee322fee4da897312090a89.tar.gz
libbb: fix empty PATH components handling
function old new delta find_execable 81 86 +5 exists_execable 71 66 -5 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/execable.c')
-rw-r--r--libbb/execable.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/libbb/execable.c b/libbb/execable.c
index 178a00a5f..a3caea6f9 100644
--- a/libbb/execable.c
+++ b/libbb/execable.c
@@ -30,6 +30,14 @@ int FAST_FUNC execable_file(const char *name)
*/
char* FAST_FUNC find_execable(const char *filename, char **PATHp)
{
+ /* About empty components in $PATH:
+ * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
+ * 8.3 Other Environment Variables - PATH
+ * A zero-length prefix is a legacy feature that indicates the current
+ * working directory. It appears as two adjacent colons ( "::" ), as an
+ * initial colon preceding the rest of the list, or as a trailing colon
+ * following the rest of the list.
+ */
char *p, *n;
p = *PATHp;
@@ -37,14 +45,15 @@ char* FAST_FUNC find_execable(const char *filename, char **PATHp)
n = strchr(p, ':');
if (n)
*n++ = '\0';
- if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
- p = concat_path_file(p, filename);
- if (execable_file(p)) {
- *PATHp = n;
- return p;
- }
- free(p);
+ p = concat_path_file(
+ p[0] ? p : ".", /* handle "::" case */
+ filename
+ );
+ if (execable_file(p)) {
+ *PATHp = n;
+ return p;
}
+ free(p);
p = n;
} /* on loop exit p == NULL */
return p;
@@ -60,11 +69,8 @@ int FAST_FUNC exists_execable(const char *filename)
char *tmp = path;
char *ret = find_execable(filename, &tmp);
free(path);
- if (ret) {
- free(ret);
- return 1;
- }
- return 0;
+ free(ret);
+ return ret != NULL;
}
#if ENABLE_FEATURE_PREFER_APPLETS