mirror of
https://github.com/systemd/systemd.git
synced 2025-03-25 18:50:18 +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.
This commit is contained in:
parent
bb2aee7d11
commit
33e1a5d8d3
@ -638,16 +638,27 @@ int find_binary(const char *name, char **ret) {
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
if (is_dir(j, true))
|
||||
continue;
|
||||
|
||||
if (access(j, X_OK) >= 0) {
|
||||
/* Found it! */
|
||||
_cleanup_free_ char *with_dash;
|
||||
|
||||
if (ret)
|
||||
*ret = path_simplify(TAKE_PTR(j), false);
|
||||
with_dash = strjoin(j, "/");
|
||||
if (!with_dash)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
/* If this passes, it must be a directory, and so should be skipped. */
|
||||
if (access(with_dash, X_OK) >= 0)
|
||||
continue;
|
||||
|
||||
/**
|
||||
* 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(TAKE_PTR(j), false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* PATH entries which we don't have access to are ignored, as per tradition. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user