git: 4daf2d3e7db5 - main - posix_spawn: use rfork_thread on all arches
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Jan 2026 02:27:21 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=4daf2d3e7db53a113108f9a02ceaf5051d416184
commit 4daf2d3e7db53a113108f9a02ceaf5051d416184
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-01-26 16:09:18 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-01-28 02:26:52 +0000
posix_spawn: use rfork_thread on all arches
Do not allocate or switch to the custom stack on non-x86.
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D54898
---
lib/libc/gen/posix_spawn.c | 39 ++++++++++++++++++---------------------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c
index c64915078317..656c0f20f798 100644
--- a/lib/libc/gen/posix_spawn.c
+++ b/lib/libc/gen/posix_spawn.c
@@ -236,7 +236,6 @@ struct posix_spawn_args {
#define PSPAWN_STACK_ALIGN(sz) \
(((sz) + PSPAWN_STACK_ALIGNBYTES) & ~PSPAWN_STACK_ALIGNBYTES)
-#if defined(__i386__) || defined(__amd64__)
/*
* Below we'll assume that _RFORK_THREAD_STACK_SIZE is appropriately aligned for
* the posix_spawn() case where we do not end up calling execvpe and won't ever
@@ -245,7 +244,6 @@ struct posix_spawn_args {
#define _RFORK_THREAD_STACK_SIZE 4096
_Static_assert((_RFORK_THREAD_STACK_SIZE % PSPAWN_STACK_ALIGNMENT) == 0,
"Inappropriate stack size alignment");
-#endif
static int
_posix_spawn_thr(void *data)
@@ -287,12 +285,14 @@ do_posix_spawn(pid_t *pid, const char *path,
pid_t p;
int pfd;
bool do_pfd;
-#ifdef _RFORK_THREAD_STACK_SIZE
char *stack;
- size_t cnt, stacksz;
+ size_t stacksz;
+#if defined(__i386__) || defined(__amd64__)
stacksz = _RFORK_THREAD_STACK_SIZE;
if (use_env_path) {
+ size_t cnt;
+
/*
* We need to make sure we have enough room on the stack for the
* potential alloca() in execvPe if it gets kicked back an
@@ -319,6 +319,9 @@ do_posix_spawn(pid_t *pid, const char *path,
return (ENOMEM);
stacksz = (((uintptr_t)stack + stacksz) & ~PSPAWN_STACK_ALIGNBYTES) -
(uintptr_t)stack;
+#else
+ stack = NULL;
+ stacksz = 0;
#endif
psa.path = path;
psa.fa = fa;
@@ -341,13 +344,16 @@ do_posix_spawn(pid_t *pid, const char *path,
* a special property of the libthr rtld locks ensure that
* rtld is operational in the child. In particular, libthr
* rtld locks do not store owner' tid into the lock word.
- */
-#ifdef _RFORK_THREAD_STACK_SIZE
- /*
- * x86 stores the return address on the stack, so rfork(2) cannot work
- * as-is because the child would clobber the return address of the
- * parent. Because of this, we must use rfork_thread instead while
- * almost every other arch stores the return address in a register.
+ *
+ * x86 stores the return address on the stack, so rfork(2)
+ * cannot work as-is because the child would clobber the
+ * return address of the parent. Because of this, we must use
+ * rfork_thread instead.
+ *
+ * Every other architecture stores the return address in a
+ * register, the trivial rfork_thread() wrapper is provided
+ * for them. The only minor drawback is that the stack is
+ * temporarily allocated.
*/
if (do_pfd) {
p = pdrfork_thread(&pfd, PD_CLOEXEC | (*sa)->sa_pdflags,
@@ -357,16 +363,7 @@ do_posix_spawn(pid_t *pid, const char *path,
&psa);
}
free(stack);
-#else
- if (do_pfd) {
- p = pdrfork(&pfd, PD_CLOEXEC | (*sa)->sa_pdflags, RFSPAWN);
- } else {
- p = rfork(RFSPAWN);
- }
- if (p == 0)
- /* _posix_spawn_thr does not return */
- _posix_spawn_thr(&psa);
-#endif
+
/*
* The above block should leave us in a state where we've either
* succeeded and we're ready to process the results, or we need to