summaryrefslogtreecommitdiffstats
path: root/src/xspawn.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2025-06-15 12:33:38 -0400
committerTavian Barnes <tavianator@tavianator.com>2025-06-15 12:35:40 -0400
commit134aa5d1c0bc71ec6cbf8f18f803976d6b60b0cc (patch)
treeff45374e19339f720ff5058413134ab1e2970a8e /src/xspawn.c
parent38f3e3e7ba210bbc45c2077102c308ed8abae061 (diff)
downloadbfs-134aa5d1c0bc71ec6cbf8f18f803976d6b60b0cc.tar.xz
xspawn: Work around a NetBSD posix_spawn() bug
NetBSD's posix_spawn() surprisingly has the same bug as its posix_spawnp(): the executable is resolved before the file actions. Detect this case and work around it by falling back to fork()/exec() if we need to.
Diffstat (limited to 'src/xspawn.c')
-rw-r--r--src/xspawn.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/xspawn.c b/src/xspawn.c
index 7fa16b7..7ead45a 100644
--- a/src/xspawn.c
+++ b/src/xspawn.c
@@ -232,6 +232,11 @@ int bfs_spawn_adddup2(struct bfs_spawn *ctx, int oldfd, int newfd) {
*/
#define BFS_POSIX_SPAWNP_AFTER_FCHDIR !(__APPLE__ || __NetBSD__)
+/**
+ * NetBSD even resolves the executable before file actions with posix_spawn()!
+ */
+#define BFS_POSIX_SPAWN_AFTER_FCHDIR !__NetBSD__
+
int bfs_spawn_addfchdir(struct bfs_spawn *ctx, int fd) {
struct bfs_spawn_action *action = bfs_spawn_action(BFS_SPAWN_FCHDIR);
if (!action) {
@@ -553,6 +558,12 @@ static bool bfs_use_posix_spawn(const struct bfs_resolver *res, const struct bfs
}
#endif
+#if !BFS_POSIX_SPAWN_AFTER_FCHDIR
+ if (res->exe[0] != '/' && bfs_spawn_will_chdir(ctx)) {
+ return false;
+ }
+#endif
+
return true;
}