diff options
author | wm4 <wm4@nowhere> | 2020-05-15 16:13:28 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2020-05-15 16:37:41 +0200 |
commit | 5309497727debfe1b268f915c5a41bdbe93ad9de (patch) | |
tree | 7c93ad237e5e8df5a0634352c7f9d4547eb29ed5 /input | |
parent | a58b2df3f84da9c19e4900e2524036a176c16c7a (diff) | |
download | mpv-5309497727debfe1b268f915c5a41bdbe93ad9de.tar.bz2 mpv-5309497727debfe1b268f915c5a41bdbe93ad9de.tar.xz |
subprocess: replace posix_spawnp() with fork()
This code runs posix_spawnp() within a fork() in some cases, in order to
"disown" processes which are meant as being started detached. But
posix_spawnp() is not marked as async-signal-safe, so what we do is not
allowed. It could for example cause deadlocks, depending on
implementation and luck at runtime. Turns out posix_spawnp() is useless
crap.
Replace it with "classic" fork() to ensure correctness.
We could probably use another mechanism to start a process "disowned"
than doing a double-fork(). The only problem with "disowning" a process
is calling setsid() (which posix_spawnp() didn't support, but maybe will
in newer revisions), and removing as as parent from the child process
(the double-fork() will make PID 1 the parent). But there is no good way
to either remove us as parent, or to "reap" the PID in a way that is
safe and less of a mess than the current code. This is because
POSIX/UNIX is a miserable heap of shit. (Less shit than "alternatives"
like win32, no doubt.)
Because POSIX/UNIX is a miserable heap of shit, execvp() is also not
specified as async-signal-safe. It's funny how you can run a full
fledged HTTP server in an async-signal-safe context, but not start a
shitty damn process. Unix is really, really, really extremely bad at
this process management stuff. So we reimplement execvp() in an
async-signal-safe way.
The new code assumes that CLOEXEC is a thing. Since POSIX/UNIX is such a
heap of shit, O_CLOEXEC and FD_CLOEXEC were (probably) added at
different times, but both must be present. io.h defines them to 0 if
they don't exist, and in this case the code will error out at runtime.
Surely we could do without CLOEXEC via fallback, but I'll do that only
if at least 1 bug is reported wrt. this issue.
The idea how to report exec() failure or success is from musl. The way
as_execvpe() is also inspired by musl (for example, the list of error
codes that should make it fail is the same as in musl's code).
Diffstat (limited to 'input')
0 files changed, 0 insertions, 0 deletions