]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
path-util: split out common part in find_executable_full()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 22 Aug 2021 21:09:14 +0000 (06:09 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 23 Aug 2021 17:04:24 +0000 (02:04 +0900)
src/basic/path-util.c

index fe799da20b6ce73071f965fcf19a224f60d76ab2..d11f254a9f6af8927844d418dcdd28a8d6d4bc03 100644 (file)
@@ -639,49 +639,53 @@ static int check_x_access(const char *path, int *ret_fd) {
         return 0;
 }
 
-int find_executable_full(const char *name, const char *root, bool use_path_envvar, char **ret_filename, int *ret_fd) {
-        int last_error, r;
-        const char *p = NULL;
+static int find_executable_impl(const char *name, const char *root, char **ret_filename, int *ret_fd) {
+        _cleanup_close_ int fd = -1;
+        _cleanup_free_ char *path_name = NULL;
+        int r;
 
         assert(name);
 
-        if (is_path(name)) {
-                _cleanup_close_ int fd = -1;
-                _cleanup_free_ char *path_name = NULL;
+        /* Function chase_symlinks() is invoked only when root is not NULL, as using it regardless of
+         * root value would alter the behavior of existing callers for example: /bin/sleep would become
+         * /usr/bin/sleep when find_executables is called. Hence, this function should be invoked when
+         * needed to avoid unforeseen regression or other complicated changes. */
+        if (root) {
+                r = chase_symlinks(name,
+                                   root,
+                                   CHASE_PREFIX_ROOT,
+                                   &path_name,
+                                   /* ret_fd= */ NULL); /* prefix root to name in case full paths are not specified */
+                if (r < 0)
+                        return r;
 
-                /* Function chase_symlinks() is invoked only when root is not NULL,
-                 * as using it regardless of root value would alter the behavior
-                 * of existing callers for example: /bin/sleep would become
-                 * /usr/bin/sleep when find_executables is called. Hence, this function
-                 * should be invoked when needed to avoid unforeseen regression or other
-                 * complicated changes. */
-                if (root) {
-                        r = chase_symlinks(name,
-                                           root,
-                                           CHASE_PREFIX_ROOT,
-                                           &path_name,
-                                           /* ret_fd= */ NULL); /* prefix root to name in case full paths are not specified */
-                        if (r < 0)
-                                return r;
+                name = path_name;
+        }
 
-                        name = path_name;
-                }
+        r = check_x_access(name, ret_fd ? &fd : NULL);
+        if (r < 0)
+                return r;
 
-                r = check_x_access(name, ret_fd ? &fd : NULL);
+        if (ret_filename) {
+                r = path_make_absolute_cwd(name, ret_filename);
                 if (r < 0)
                         return r;
+        }
 
-                if (ret_filename) {
-                        r = path_make_absolute_cwd(name, ret_filename);
-                        if (r < 0)
-                                return r;
-                }
+        if (ret_fd)
+                *ret_fd = TAKE_FD(fd);
 
-                if (ret_fd)
-                        *ret_fd = TAKE_FD(fd);
+        return 0;
+}
 
-                return 0;
-        }
+int find_executable_full(const char *name, const char *root, bool use_path_envvar, char **ret_filename, int *ret_fd) {
+        int last_error, r;
+        const char *p = NULL;
+
+        assert(name);
+
+        if (is_path(name))
+                return find_executable_impl(name, root, ret_filename, ret_fd);
 
         if (use_path_envvar)
                 /* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the
@@ -695,7 +699,6 @@ int find_executable_full(const char *name, const char *root, bool use_path_envva
         /* Resolve a single-component name to a full path */
         for (;;) {
                 _cleanup_free_ char *element = NULL;
-                _cleanup_close_ int fd = -1;
 
                 r = extract_first_word(&p, &element, ":", EXTRACT_RELAX|EXTRACT_DONT_COALESCE_SEPARATORS);
                 if (r < 0)
@@ -709,24 +712,7 @@ int find_executable_full(const char *name, const char *root, bool use_path_envva
                 if (!path_extend(&element, name))
                         return -ENOMEM;
 
-                if (root) {
-                        char *path_name;
-
-                        r = chase_symlinks(element,
-                                           root,
-                                           CHASE_PREFIX_ROOT,
-                                           &path_name,
-                                           /* ret_fd= */ NULL);
-                        if (r < 0) {
-                                if (r != -EACCES)
-                                        last_error = r;
-                                continue;
-                        }
-
-                        free_and_replace(element, path_name);
-                }
-
-                r = check_x_access(element, ret_fd ? &fd : NULL);
+                r = find_executable_impl(element, root, ret_filename, ret_fd);
                 if (r < 0) {
                         /* PATH entries which we don't have access to are ignored, as per tradition. */
                         if (r != -EACCES)
@@ -735,11 +721,6 @@ int find_executable_full(const char *name, const char *root, bool use_path_envva
                 }
 
                 /* Found it! */
-                if (ret_filename)
-                        *ret_filename = path_simplify(TAKE_PTR(element));
-                if (ret_fd)
-                        *ret_fd = TAKE_FD(fd);
-
                 return 0;
         }