diff options
Diffstat (limited to 'main/musl/0010-make-posix_spawn-and-functions-that-use-it-use-CLONE.patch')
-rw-r--r-- | main/musl/0010-make-posix_spawn-and-functions-that-use-it-use-CLONE.patch | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/main/musl/0010-make-posix_spawn-and-functions-that-use-it-use-CLONE.patch b/main/musl/0010-make-posix_spawn-and-functions-that-use-it-use-CLONE.patch new file mode 100644 index 000000000..d6260a5f9 --- /dev/null +++ b/main/musl/0010-make-posix_spawn-and-functions-that-use-it-use-CLONE.patch @@ -0,0 +1,50 @@ +From 53761b469221fbe062629c50249e3d534573eda9 Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Wed, 17 Jul 2013 13:54:41 -0400 +Subject: [PATCH 10/10] make posix_spawn (and functions that use it) use + CLONE_VFORK flag + +this is both a minor scheduling optimization and a workaround for a +difficult-to-fix bug in qemu app-level emulation. + +from the scheduling standpoint, it makes no sense to schedule the +parent thread again until the child has exec'd or exited, since the +parent will immediately block again waiting for it. + +on the qemu side, as regular application code running on an underlying +libc, qemu cannot make arbitrary clone syscalls itself without +confusing the underlying implementation. instead, it breaks them down +into either fork-like or pthread_create-like cases. it was treating +the code in posix_spawn as pthread_create-like, due to CLONE_VM, which +caused horribly wrong behavior: CLONE_FILES broke the synchronization +mechanism, CLONE_SIGHAND broke the parent's signals, and CLONE_THREAD +caused the child's exec to end the parent -- if it hadn't already +crashed. however, qemu special-cases CLONE_VFORK and emulates that +with fork, even when CLONE_VM is also specified. this also gives +incorrect semantics for code that really needs the memory sharing, but +posix_spawn does not make use of the vm sharing except to avoid +momentary double commit charge. + +programs using posix_spawn (including via popen) should now work +correctly under qemu app-level emulation. +--- + src/process/posix_spawn.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c +index e6a031c..68cf795 100644 +--- a/src/process/posix_spawn.c ++++ b/src/process/posix_spawn.c +@@ -138,7 +138,8 @@ int __posix_spawnx(pid_t *restrict res, const char *restrict path, + args.envp = envp; + pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask); + +- pid = __clone(child, stack+sizeof stack, CLONE_VM|SIGCHLD, &args); ++ pid = __clone(child, stack+sizeof stack, ++ CLONE_VM|CLONE_VFORK|SIGCHLD, &args); + close(args.p[1]); + + if (pid > 0) { +-- +1.8.3.2 + |