]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/path-util: enhance find_executable() for the fixed path case
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 17 Sep 2020 12:32:17 +0000 (14:32 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 18 Sep 2020 13:28:48 +0000 (15:28 +0200)
src/basic/path-util.c
src/basic/path-util.h
src/test/test-path-util.c

index cecee3a5415901251292fdbc04cec4e89c052aba..a36cf8332c2df79fa1557bbe0d32138a886fed19 100644 (file)
@@ -585,9 +585,9 @@ char* path_join_internal(const char *first, ...) {
         return joined;
 }
 
-int find_executable(const char *name, char **ret) {
+int find_executable_full(const char *name, bool use_path_envvar, char **ret) {
         int last_error, r;
-        const char *p;
+        const char *p = NULL;
 
         assert(name);
 
@@ -604,8 +604,10 @@ int find_executable(const char *name, char **ret) {
                 return 0;
         }
 
-        /* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the binary. */
-        p = getenv("PATH");
+        if (use_path_envvar)
+                /* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the
+                 * binary. */
+                p = getenv("PATH");
         if (!p)
                 p = DEFAULT_PATH;
 
index 3d5244833437b2e25d74fe485c95989abdebb699..bd8c14903e54094761f71121a71e5eb6e28f33a5 100644 (file)
@@ -88,7 +88,10 @@ int path_strv_make_absolute_cwd(char **l);
 char** path_strv_resolve(char **l, const char *root);
 char** path_strv_resolve_uniq(char **l, const char *root);
 
-int find_executable(const char *name, char **filename);
+int find_executable_full(const char *name, bool use_path_envvar, char **ret);
+static inline int find_executable(const char *name, char **ret) {
+        return find_executable_full(name, true, ret);
+}
 
 bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
 
index 83336fc7feddcc2f22314ed69dd0bd849a95b193..e98c19dd6cc5e2bc7f512f46bd585261cfa22c76 100644 (file)
@@ -164,6 +164,42 @@ static void test_path_equal_root(void) {
         assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW));
 }
 
+static void test_find_executable_full(void) {
+        char *p;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(find_executable_full("sh", true, &p) == 0);
+        puts(p);
+        assert_se(streq(basename(p), "sh"));
+        free(p);
+
+        assert_se(find_executable_full("sh", false, &p) == 0);
+        puts(p);
+        assert_se(streq(basename(p), "sh"));
+        free(p);
+
+        _cleanup_free_ char *oldpath = NULL;
+        p = getenv("PATH");
+        if (p)
+                assert_se(oldpath = strdup(p));
+
+        assert_se(unsetenv("PATH") >= 0);
+
+        assert_se(find_executable_full("sh", true, &p) == 0);
+        puts(p);
+        assert_se(streq(basename(p), "sh"));
+        free(p);
+
+        assert_se(find_executable_full("sh", false, &p) == 0);
+        puts(p);
+        assert_se(streq(basename(p), "sh"));
+        free(p);
+
+        if (oldpath)
+                assert_se(setenv("PATH", oldpath, true) >= 0);
+}
+
 static void test_find_executable(const char *self) {
         char *p;
 
@@ -176,8 +212,7 @@ static void test_find_executable(const char *self) {
 
         assert_se(find_executable(self, &p) == 0);
         puts(p);
-        /* libtool might prefix the binary name with "lt-" */
-        assert_se(endswith(p, "/lt-test-path-util") || endswith(p, "/test-path-util"));
+        assert_se(endswith(p, "/test-path-util"));
         assert_se(path_is_absolute(p));
         free(p);
 
@@ -187,8 +222,18 @@ static void test_find_executable(const char *self) {
         assert_se(path_is_absolute(p));
         free(p);
 
+        assert_se(find_executable("/bin/touch", &p) == 0);
+        assert_se(streq(p, "/bin/touch"));
+        free(p);
+
+        assert_se(find_executable("touch", &p) == 0);
+        assert_se(path_is_absolute(p));
+        assert_se(streq(basename(p), "touch"));
+        free(p);
+
         assert_se(find_executable("xxxx-xxxx", &p) == -ENOENT);
         assert_se(find_executable("/some/dir/xxxx-xxxx", &p) == -ENOENT);
+        assert_se(find_executable("/proc/filesystems", &p) == -EACCES);
 }
 
 static void test_prefixes(void) {
@@ -670,6 +715,7 @@ int main(int argc, char **argv) {
         test_print_paths();
         test_path();
         test_path_equal_root();
+        test_find_executable_full();
         test_find_executable(argv[0]);
         test_prefixes();
         test_path_join();