* Eric Blake:
Does anyone know if glibc guarantees that opendir/readdir in between
multi-threaded fork() and exec() is safe, even though POSIX does not
guarantee that safety in general?
glibc supports malloc after multi-threaded fork as an extension (or as
a bug, because it makes malloc not async-signal-safe).
Lots of programs depend on this. OpenJDK even calls malloc after
vfork, which is not officially supported (but of course we can't break
OpenJDK).
I know that one approach to avoid
having to close all fds is religiously using O_CLOEXEC everywhere (so
that the race window of having an fd that would leak is not possible),
but that's also an expensive audit, compared to just ensuring that
things are closed after fork(). Are there any other ideas out there
that we should be aware of (and no, pthread_atfork is not a sane idea)?
(various BSD systems have the closefrom() syscall which is more
efficient than lots of close() calls; and Linux may be adding something
similar
https://lwn.net/Articles/789023/), Is there any saner way to
close all unneeded fds that were not properly marked O_CLOEXEC by an
application linking against a multithreaded lib that must perform fork/exec?
I tried to add getdents64 (which got committed, but may yet move from
<unistd.h> to <dirent.h>, to match musl) and <sys/direntries.h> (which
did not) in glibc 2.30. Those interfaces are async-signal-safe
(except on some MIPS variants, where getdents64 has complex
emulation).
If you do not want to use opendir/readdir, issuing getdents64 directly
and parsing the buffer is your best option right now. (Lowering the
RLIMIT_NOFILE limit does not enable probing for stray descriptors,
unfortunately.) But opendir/readdir after fork should be fine,
really.