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:
Chris Down 2020-08-26 18:49:27 +01:00
parent bb2aee7d11
commit 33e1a5d8d3

View file

@ -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. */