From 51b271ead7c1e767607064a57a3024bb7d9c2e2f Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Mon, 22 Jul 2024 22:17:05 +0200 Subject: [PATCH 1/2] path-util: trivial cleanup for find_executable_full() --- src/basic/path-util.c | 69 +++++++++++++++++++++---------------------- src/basic/path-util.h | 8 ++++- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 068fb42960..0b4d7b6cf7 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -653,7 +653,7 @@ static int find_executable_impl(const char *name, const char *root, char **ret_f * /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) { - /* prefix root to name in case full paths are not specified */ + /* prefix root to name in case full paths are not specified */ r = chase(name, root, CHASE_PREFIX_ROOT, &path_name, /* ret_fd= */ NULL); if (r < 0) return r; @@ -680,19 +680,42 @@ static int find_executable_impl(const char *name, const char *root, char **ret_f int find_executable_full( const char *name, const char *root, - char **exec_search_path, + char * const *exec_search_path, bool use_path_envvar, char **ret_filename, int *ret_fd) { int last_error = -ENOENT, r = 0; - const char *p = NULL; assert(name); if (is_path(name)) return find_executable_impl(name, root, ret_filename, ret_fd); + if (exec_search_path) { + STRV_FOREACH(element, exec_search_path) { + _cleanup_free_ char *full_path = NULL; + + if (!path_is_absolute(*element)) { + log_debug("Exec search path '%s' isn't absolute, ignoring.", *element); + continue; + } + + full_path = path_join(*element, name); + if (!full_path) + return -ENOMEM; + + r = find_executable_impl(full_path, root, ret_filename, ret_fd); + if (r >= 0) + return 0; + if (r != -EACCES) + last_error = r; + } + return last_error; + } + + const char *p = NULL; + if (use_path_envvar) /* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the * binary. */ @@ -700,28 +723,6 @@ int find_executable_full( if (!p) p = default_PATH(); - if (exec_search_path) { - STRV_FOREACH(element, exec_search_path) { - _cleanup_free_ char *full_path = NULL; - - if (!path_is_absolute(*element)) - continue; - - full_path = path_join(*element, name); - if (!full_path) - return -ENOMEM; - - r = find_executable_impl(full_path, root, ret_filename, ret_fd); - if (r < 0) { - if (r != -EACCES) - last_error = r; - continue; - } - return 0; - } - return last_error; - } - /* Resolve a single-component name to a full path */ for (;;) { _cleanup_free_ char *element = NULL; @@ -732,22 +733,20 @@ int find_executable_full( if (r == 0) break; - if (!path_is_absolute(element)) + if (!path_is_absolute(element)) { + log_debug("Exec search path '%s' isn't absolute, ignoring.", element); continue; + } if (!path_extend(&element, name)) return -ENOMEM; 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) - last_error = r; - continue; - } - - /* Found it! */ - return 0; + if (r >= 0) /* Found it! */ + return 0; + /* PATH entries which we don't have access to are ignored, as per tradition. */ + if (r != -EACCES) + last_error = r; } return last_error; diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 8b5c8fbf3c..dff5a3a549 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -115,7 +115,13 @@ 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_full(const char *name, const char *root, char **exec_search_path, bool use_path_envvar, char **ret_filename, int *ret_fd); +int find_executable_full( + const char *name, + const char *root, + char * const *exec_search_path, + bool use_path_envvar, + char **ret_filename, + int *ret_fd); static inline int find_executable(const char *name, char **ret_filename) { return find_executable_full(name, /* root= */ NULL, NULL, true, ret_filename, NULL); } From 0e7eda91f4bacc3a84733d392f7954b1950c793c Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Mon, 22 Jul 2024 22:17:24 +0200 Subject: [PATCH 2/2] path-util: simplify final path for find_executable() Currently, systemd-run ./test.sh would set Description= to $PWD/./test.sh. This is quite ugly. --- src/basic/path-util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 0b4d7b6cf7..78ba10ed80 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -669,6 +669,8 @@ static int find_executable_impl(const char *name, const char *root, char **ret_f r = path_make_absolute_cwd(name, ret_filename); if (r < 0) return r; + + path_simplify(*ret_filename); } if (ret_fd)