mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-20 14:03:39 +03:00
path: Improve $PATH search directory case
Previously: 1. last_error wouldn't be updated with errors from is_dir; 2. We'd always issue a stat(), even for binaries without execute; 3. We used stat() instead of access(), which is cheaper. This change avoids all of those, by only checking inside X_OK-positive case whether access() works on the path with an extra slash appended. Thanks to Lennart for the suggestion. (cherry picked from commit 33e1a5d8d3f792e1d98377fe439e123231032ec7) (cherry picked from commit a4236a27644705e58836f5d547d5aef50d568c11) (cherry picked from commit 6a30d4e98032575d385a09d15782be74cbef6dfe) (cherry picked from commit 0783b4f8cecda4f21e9021495377e2c807a32a5e)
This commit is contained in:
parent
67d1efbc89
commit
78a267e2e3
@ -640,19 +640,28 @@ int find_binary(const char *name, char **ret) {
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
if (is_dir(j, true))
|
||||
if (access(j, X_OK) >= 0) {
|
||||
_cleanup_free_ char *with_dash;
|
||||
|
||||
with_dash = strjoin(j, "/");
|
||||
if (!with_dash)
|
||||
return -ENOMEM;
|
||||
|
||||
/* If this passes, it must be a directory, and so should be skipped. */
|
||||
if (access(with_dash, X_OK) >= 0)
|
||||
continue;
|
||||
|
||||
if (access(j, X_OK) >= 0) {
|
||||
/**
|
||||
* We can't just `continue` inverting this case, since we need to update last_error.
|
||||
*/
|
||||
if (errno == ENOTDIR) {
|
||||
/* Found it! */
|
||||
|
||||
if (ret) {
|
||||
*ret = path_simplify(j, false);
|
||||
j = NULL;
|
||||
}
|
||||
if (ret)
|
||||
*ret = path_simplify(TAKE_PTR(j), false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* PATH entries which we don't have access to are ignored, as per tradition. */
|
||||
if (errno != EACCES)
|
||||
|
Loading…
x
Reference in New Issue
Block a user