summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/xspawn.c13
-rw-r--r--tests/xspawn.c2
2 files changed, 13 insertions, 2 deletions
diff --git a/src/xspawn.c b/src/xspawn.c
index 33e5a4a..2c64011 100644
--- a/src/xspawn.c
+++ b/src/xspawn.c
@@ -426,8 +426,17 @@ static int bfs_resolve_early(struct bfs_resolver *res, const char *exe, const st
};
if (bfs_can_skip_resolve(res, ctx)) {
- res->done = true;
- return 0;
+ // Do this check eagerly, even though posix_spawn()/execv() also
+ // would, because:
+ //
+ // - faccessat() is faster than fork()/clone() + execv()
+ // - posix_spawn() is not guaranteed to report ENOENT
+ if (xfaccessat(AT_FDCWD, exe, X_OK) == 0) {
+ res->done = true;
+ return 0;
+ } else {
+ return -1;
+ }
}
res->path = getenv("PATH");
diff --git a/tests/xspawn.c b/tests/xspawn.c
index b1d6dc1..f48e220 100644
--- a/tests/xspawn.c
+++ b/tests/xspawn.c
@@ -179,6 +179,8 @@ static bool check_resolve(void) {
ret &= bfs_echeck(!bfs_spawn_resolve("eW6f5RM9Qi") && errno == ENOENT);
+ ret &= bfs_echeck(!bfs_spawn_resolve("bin/eW6f5RM9Qi") && errno == ENOENT);
+
return ret;
}