summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-11-15 09:21:53 -0500
committerTavian Barnes <tavianator@tavianator.com>2023-11-15 09:21:53 -0500
commit8b312eb6553235c36f5483d4e46c5034dcc03ce2 (patch)
treee50343acd34d92cfb146068a78624568ab903a6e
parentcc7d66416b91e0972c1022d0a835804a63ab7ab1 (diff)
downloadbfs-8b312eb6553235c36f5483d4e46c5034dcc03ce2.tar.xz
xspawn: API tweaks
-rw-r--r--src/exec.c6
-rw-r--r--src/xspawn.c52
-rw-r--r--src/xspawn.h33
3 files changed, 48 insertions, 43 deletions
diff --git a/src/exec.c b/src/exec.c
index 87250ac..3ff6f92 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -362,9 +362,7 @@ static int bfs_exec_spawn(const struct bfs_exec *execbuf) {
return -1;
}
- if (bfs_spawn_setflags(&spawn, BFS_SPAWN_USE_PATH) != 0) {
- goto fail;
- }
+ spawn.flags |= BFS_SPAWN_USE_PATH;
if (execbuf->wd_fd >= 0) {
if (bfs_spawn_addfchdir(&spawn, execbuf->wd_fd) != 0) {
@@ -374,7 +372,7 @@ static int bfs_exec_spawn(const struct bfs_exec *execbuf) {
// Reset RLIMIT_NOFILE if necessary, to avoid breaking applications that use select()
if (rlim_cmp(ctx->orig_nofile.rlim_cur, ctx->cur_nofile.rlim_cur) < 0) {
- if (bfs_spawn_addsetrlimit(&spawn, RLIMIT_NOFILE, &ctx->orig_nofile) != 0) {
+ if (bfs_spawn_setrlimit(&spawn, RLIMIT_NOFILE, &ctx->orig_nofile) != 0) {
goto fail;
}
}
diff --git a/src/xspawn.c b/src/xspawn.c
index 6a2ebba..3974768 100644
--- a/src/xspawn.c
+++ b/src/xspawn.c
@@ -47,14 +47,14 @@ int bfs_spawn_init(struct bfs_spawn *ctx) {
ctx->flags = BFS_SPAWN_USE_POSIX;
SLIST_INIT(ctx);
- errno = posix_spawnattr_init(&ctx->attr);
+ errno = posix_spawn_file_actions_init(&ctx->actions);
if (errno != 0) {
return -1;
}
- errno = posix_spawn_file_actions_init(&ctx->actions);
+ errno = posix_spawnattr_init(&ctx->attr);
if (errno != 0) {
- posix_spawnattr_destroy(&ctx->attr);
+ posix_spawn_file_actions_destroy(&ctx->actions);
return -1;
}
@@ -62,8 +62,8 @@ int bfs_spawn_init(struct bfs_spawn *ctx) {
}
int bfs_spawn_destroy(struct bfs_spawn *ctx) {
- posix_spawn_file_actions_destroy(&ctx->actions);
posix_spawnattr_destroy(&ctx->attr);
+ posix_spawn_file_actions_destroy(&ctx->actions);
for_slist (struct bfs_spawn_action, action, ctx) {
free(action);
@@ -72,8 +72,22 @@ int bfs_spawn_destroy(struct bfs_spawn *ctx) {
return 0;
}
-int bfs_spawn_setflags(struct bfs_spawn *ctx, enum bfs_spawn_flags flags) {
- ctx->flags |= flags;
+/** Set some posix_spawnattr flags. */
+static inline int bfs_spawn_addflags(struct bfs_spawn *ctx, short flags) {
+ short prev;
+ errno = posix_spawnattr_getflags(&ctx->attr, &prev);
+ if (errno != 0) {
+ return -1;
+ }
+
+ short next = prev | flags;
+ if (next != prev) {
+ errno = posix_spawnattr_setflags(&ctx->attr, next);
+ if (errno != 0) {
+ return -1;
+ }
+ }
+
return 0;
}
@@ -150,13 +164,15 @@ int bfs_spawn_addfchdir(struct bfs_spawn *ctx, int fd) {
# endif
#endif
-#if BFS_HAS_POSIX_SPAWN_FCHDIR || BFS_HAS_POSIX_SPAWN_FCHDIR_NP
+#if BFS_HAS_POSIX_SPAWN_FCHDIR
+# define BFS_POSIX_SPAWN_FCHDIR posix_spawn_file_actions_addfchdir
+#elif BFS_HAS_POSIX_SPAWN_FCHDIR_NP
+# define BFS_POSIX_SPAWN_FCHDIR posix_spawn_file_actions_addfchdir_np
+#endif
+
+#ifdef BFS_POSIX_SPAWN_FCHDIR
if (ctx->flags & BFS_SPAWN_USE_POSIX) {
-# if BFS_HAS_POSIX_SPAWN_FCHDIR
- errno = posix_spawn_file_actions_addfchdir(&ctx->actions, fd);
-# else
- errno = posix_spawn_file_actions_addfchdir_np(&ctx->actions, fd);
-# endif
+ errno = BFS_POSIX_SPAWN_FCHDIR(&ctx->actions, fd);
if (errno != 0) {
free(action);
return -1;
@@ -171,22 +187,14 @@ int bfs_spawn_addfchdir(struct bfs_spawn *ctx, int fd) {
return 0;
}
-int bfs_spawn_addsetrlimit(struct bfs_spawn *ctx, int resource, const struct rlimit *rl) {
+int bfs_spawn_setrlimit(struct bfs_spawn *ctx, int resource, const struct rlimit *rl) {
struct bfs_spawn_action *action = bfs_spawn_action(BFS_SPAWN_SETRLIMIT);
if (!action) {
goto fail;
}
#ifdef POSIX_SPAWN_SETRLIMIT
- short flags;
- errno = posix_spawnattr_getflags(&ctx->attr, &flags);
- if (errno != 0) {
- goto fail;
- }
-
- flags |= POSIX_SPAWN_SETRLIMIT;
- errno = posix_spawnattr_setflags(&ctx->attr, flags);
- if (errno != 0) {
+ if (bfs_spawn_addflags(ctx, POSIX_SPAWN_SETRLIMIT) != 0) {
goto fail;
}
diff --git a/src/xspawn.h b/src/xspawn.h
index 2a3d736..e3ad1eb 100644
--- a/src/xspawn.h
+++ b/src/xspawn.h
@@ -34,59 +34,58 @@ struct bfs_spawn {
struct bfs_spawn_action *head;
struct bfs_spawn_action **tail;
- /** pthread_spawn() context, for when we can use it. */
- posix_spawnattr_t attr;
+ /** posix_spawn() context, for when we can use it. */
posix_spawn_file_actions_t actions;
+ posix_spawnattr_t attr;
};
/**
* Create a new bfs_spawn() context.
*
- * @return 0 on success, -1 on failure.
+ * @return
+ * 0 on success, -1 on failure.
*/
int bfs_spawn_init(struct bfs_spawn *ctx);
/**
* Destroy a bfs_spawn() context.
*
- * @return 0 on success, -1 on failure.
+ * @return
+ * 0 on success, -1 on failure.
*/
int bfs_spawn_destroy(struct bfs_spawn *ctx);
/**
- * Set the flags for a bfs_spawn() context.
- *
- * @return 0 on success, -1 on failure.
- */
-int bfs_spawn_setflags(struct bfs_spawn *ctx, enum bfs_spawn_flags flags);
-
-/**
* Add a close() action to a bfs_spawn() context.
*
- * @return 0 on success, -1 on failure.
+ * @return
+ * 0 on success, -1 on failure.
*/
int bfs_spawn_addclose(struct bfs_spawn *ctx, int fd);
/**
* Add a dup2() action to a bfs_spawn() context.
*
- * @return 0 on success, -1 on failure.
+ * @return
+ * 0 on success, -1 on failure.
*/
int bfs_spawn_adddup2(struct bfs_spawn *ctx, int oldfd, int newfd);
/**
* Add an fchdir() action to a bfs_spawn() context.
*
- * @return 0 on success, -1 on failure.
+ * @return
+ * 0 on success, -1 on failure.
*/
int bfs_spawn_addfchdir(struct bfs_spawn *ctx, int fd);
/**
- * Add a setrlimit() action to a bfs_spawn() context.
+ * Apply setrlimit() to a bfs_spawn() context.
*
- * @return 0 on success, -1 on failure.
+ * @return
+ * 0 on success, -1 on failure.
*/
-int bfs_spawn_addsetrlimit(struct bfs_spawn *ctx, int resource, const struct rlimit *rl);
+int bfs_spawn_setrlimit(struct bfs_spawn *ctx, int resource, const struct rlimit *rl);
/**
* Spawn a new process.