diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-08-23 06:09:14 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-08-24 02:04:24 +0900 |
commit | ded8039abe2fa39add817871841e587ccd476197 (patch) | |
tree | 6a60da48ce0245d2cbb97e0f1033529277e36140 | |
parent | 3a1220eedfb65355c387c29584380742a21917aa (diff) | |
download | systemd-ded8039abe2fa39add817871841e587ccd476197.tar.gz |
path-util: split out common part in find_executable_full()
-rw-r--r-- | src/basic/path-util.c | 93 |
1 files changed, 37 insertions, 56 deletions
diff --git a/src/basic/path-util.c b/src/basic/path-util.c index fe799da20b..d11f254a9f 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -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; } |