summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/xspawn.c11
-rw-r--r--tests/xspawn.c31
2 files changed, 29 insertions, 13 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;
}
diff --git a/tests/xspawn.c b/tests/xspawn.c
index 0244006..6864192 100644
--- a/tests/xspawn.c
+++ b/tests/xspawn.c
@@ -99,6 +99,22 @@ static int reset_path(char *old_path) {
return ret;
}
+/** Spawn the test binary and check for success. */
+static void check_spawnee(const char *exe, const struct bfs_spawn *ctx, char **argv, char **envp) {
+ pid_t pid = bfs_spawn(exe, ctx, argv, envp);
+ if (!bfs_echeck(pid >= 0, "bfs_spawn('%s')", exe)) {
+ return;
+ }
+
+ int wstatus;
+ bool exited = bfs_echeck(xwaitpid(pid, &wstatus, 0) == pid)
+ && bfs_check(WIFEXITED(wstatus));
+ if (exited) {
+ int wexit = WEXITSTATUS(wstatus);
+ bfs_check(wexit == EXIT_SUCCESS, "xspawnee: exit(%d)", wexit);
+ }
+}
+
/** Check that we resolve executables in $PATH correctly. */
static void check_use_path(bool use_posix) {
struct bfs_spawn spawn;
@@ -133,20 +149,9 @@ static void check_use_path(bool use_posix) {
}
char *argv[] = {"xspawnee", old_path, NULL};
- pid_t pid = bfs_spawn("xspawnee", &spawn, argv, envp);
- if (!bfs_echeck(pid >= 0, "bfs_spawn()")) {
- goto path;
- }
-
- int wstatus;
- bool exited = bfs_echeck(xwaitpid(pid, &wstatus, 0) == pid)
- && bfs_check(WIFEXITED(wstatus));
- if (exited) {
- int wexit = WEXITSTATUS(wstatus);
- bfs_check(wexit == EXIT_SUCCESS, "xspawnee: exit(%d)", wexit);
- }
+ check_spawnee("xspawnee", &spawn, argv, envp);
+ check_spawnee("tests/xspawnee", &spawn, argv, envp);
-path:
bfs_echeck(reset_path(old_path) == 0);
env:
for (char **var = envp; *var; ++var) {