musl/src/stdio/popen.c, branch master musl - an implementation of the standard library for Linux-based systems fix popen not to leak pipes from one child to another 2021年04月20日T18:55:10+00:00 Rich Felker dalias@aerifal.cx 2021年04月20日T18:55:10+00:00 e1a51185ceb4386481491e11f6dd39569b9e54f7 POSIX places an obscure requirement on popen which is like a limited version of close-on-exec: "The popen() function shall ensure that any streams from previous popen() calls that remain open in the parent process are closed in the new child process." if the POSIX-future 'e' mode flag is passed, producing a pipe FILE with FD_CLOEXEC on the underlying pipe, this requirement is automatically satisfied. however, for applications which use multiple concurrent popen pipes but don't request close-on-exec, fd leaks from earlier popen calls to later ones could produce deadlock situations where processes are waiting for a pipe EOF that will never happen. to fix this, iterate through all open FILEs and add close actions for those obtained from popen. this requires holding a lock on the open file list across the posix_spawn call so that additional popen FILEs are not created after the list is traversed. note that it's still possible for another popen call to start and create its pipe while the lock is held, but such pipes are created with O_CLOEXEC and only drop close-on-exec status (when 'e' flag is omitted) under control of the lock.
POSIX places an obscure requirement on popen which is like a limited
version of close-on-exec:
 "The popen() function shall ensure that any streams from previous
 popen() calls that remain open in the parent process are closed in
 the new child process."
if the POSIX-future 'e' mode flag is passed, producing a pipe FILE
with FD_CLOEXEC on the underlying pipe, this requirement is
automatically satisfied. however, for applications which use multiple
concurrent popen pipes but don't request close-on-exec, fd leaks from
earlier popen calls to later ones could produce deadlock situations
where processes are waiting for a pipe EOF that will never happen.
to fix this, iterate through all open FILEs and add close actions for
those obtained from popen. this requires holding a lock on the open
file list across the posix_spawn call so that additional popen FILEs
are not created after the list is traversed. note that it's still
possible for another popen call to start and create its pipe while the
lock is held, but such pipes are created with O_CLOEXEC and only drop
close-on-exec status (when 'e' flag is omitted) under control of the
lock.
remove spurious lock in popen 2021年04月20日T18:52:08+00:00 Rich Felker dalias@aerifal.cx 2021年04月20日T18:52:08+00:00 e74acd59a5c7d56ae0e64c4ffa5043da13ee896e the newly allocated FILE * has not yet leaked to the application and is only visible to stdio internals until popen returns. since we do not change any fields of the structure observed by libc internals, only the pipe_pid member, locking is not necessary.
the newly allocated FILE * has not yet leaked to the application and
is only visible to stdio internals until popen returns. since we do
not change any fields of the structure observed by libc internals,
only the pipe_pid member, locking is not necessary.
remove no-longer-needed special case handling in popen 2021年03月15日T14:29:20+00:00 Rich Felker dalias@aerifal.cx 2021年03月15日T14:26:21+00:00 122002f0ddf267977282f05066a0794e31661501 popen was special-casing the possibility (only possible when the parent closed stdin and/or stdout) that the child's end of the pipe was already on the final desired fd number, in which case there was no way to get rid of its close-on-exec flag in the child. commit 6fc6ca1a323bc0b6b9e9cdc8fa72221ae18fe206 made this unnecessary by implementing the POSIX-future requirement that dup2 file actions with equal source and destination fd values remove the close-on-exec flag.
popen was special-casing the possibility (only possible when the
parent closed stdin and/or stdout) that the child's end of the pipe
was already on the final desired fd number, in which case there was no
way to get rid of its close-on-exec flag in the child. commit
6fc6ca1a323bc0b6b9e9cdc8fa72221ae18fe206 made this unnecessary by
implementing the POSIX-future requirement that dup2 file actions with
equal source and destination fd values remove the close-on-exec flag.
fix special-case breakage in popen due to reversed argument order 2013年09月01日T21:02:35+00:00 Rich Felker dalias@aerifal.cx 2013年09月01日T21:02:35+00:00 fe80a8eb687f48f08e393522520f69b0c52cb297
rewrite popen to use posix_spawn instead of fragile vfork hacks 2013年03月25日T02:41:38+00:00 Rich Felker dalias@aerifal.cx 2013年03月25日T02:41:38+00:00 9cb6e6ea120cfaf1df9016883012d22fb57d43e1
clean up sloppy nested inclusion from pthread_impl.h 2012年11月08日T22:04:20+00:00 Rich Felker dalias@aerifal.cx 2012年11月08日T22:04:20+00:00 efd4d87aa472523b07889af69874259db43b3c3c this mirrors the stdio_impl.h cleanup. one header which is not strictly needed, errno.h, is left in pthread_impl.h, because since pthread functions return their error codes rather than using errno, nearly every single pthread function needs the errno constants. in a few places, rather than bringing in string.h to use memset, the memset was replaced by direct assignment. this seems to generate much better code anyway, and makes many functions which were previously non-leaf functions into leaf functions (possibly eliminating a great deal of bloat on some platforms where non-leaf functions require ugly prologue and/or epilogue).
this mirrors the stdio_impl.h cleanup. one header which is not
strictly needed, errno.h, is left in pthread_impl.h, because since
pthread functions return their error codes rather than using errno,
nearly every single pthread function needs the errno constants.
in a few places, rather than bringing in string.h to use memset, the
memset was replaced by direct assignment. this seems to generate much
better code anyway, and makes many functions which were previously
non-leaf functions into leaf functions (possibly eliminating a great
deal of bloat on some platforms where non-leaf functions require ugly
prologue and/or epilogue).
fix copy/paste error in popen changes that broke signals 2012年10月21日T17:23:03+00:00 Rich Felker dalias@aerifal.cx 2012年10月21日T17:23:03+00:00 f1b23d41cff432a8d0939af427fa005b4a4f95d7 signal mask was not being restored after fork, but instead blocked again.
signal mask was not being restored after fork, but instead blocked again.
fix usage of locks with vfork 2012年10月19日T19:02:37+00:00 Rich Felker dalias@aerifal.cx 2012年10月19日T19:02:37+00:00 599f97360389911c293e0ca4c5eb49e007377fba __release_ptc() is only valid in the parent; if it's performed in the child, the lock will be unlocked early then double-unlocked later, corrupting the lock state.
__release_ptc() is only valid in the parent; if it's performed in the
child, the lock will be unlocked early then double-unlocked later,
corrupting the lock state.
overhaul system() and popen() to use vfork; fix various related bugs 2012年10月18日T19:58:23+00:00 Rich Felker dalias@aerifal.cx 2012年10月18日T19:58:23+00:00 44eb4d8b9b7b3b539bcd4e311e9d7c8e2acf8d80 since we target systems without overcommit, special care should be taken that system() and popen(), like posix_spawn(), do not fail in processes whose commit charges are too high to allow ordinary forking. this in turn requires special precautions to ensure that the parent process's signal handlers do not end up running in the shared-memory child, where they could corrupt the state of the parent process. popen has also been updated to use pipe2, so it does not have a fd-leak race in multi-threaded programs. since pipe2 is missing on older kernels, (non-atomic) emulation has been added. some silly bugs in the old code should be gone too.
since we target systems without overcommit, special care should be
taken that system() and popen(), like posix_spawn(), do not fail in
processes whose commit charges are too high to allow ordinary forking.
this in turn requires special precautions to ensure that the parent
process's signal handlers do not end up running in the shared-memory
child, where they could corrupt the state of the parent process.
popen has also been updated to use pipe2, so it does not have a
fd-leak race in multi-threaded programs. since pipe2 is missing on
older kernels, (non-atomic) emulation has been added.
some silly bugs in the old code should be gone too.
make popen cancellation-safe 2012年06月20日T18:39:50+00:00 Rich Felker dalias@aerifal.cx 2012年06月20日T18:39:50+00:00 9c21f4342c787e04a9e31ad8a1d87a65c89968ca close was the only cancellation point called from popen, but it left popen with major resource leaks if any call to close got cancelled. the easiest, cheapest fix is just to use a non-cancellable close function.
close was the only cancellation point called from popen, but it left
popen with major resource leaks if any call to close got cancelled.
the easiest, cheapest fix is just to use a non-cancellable close
function.

AltStyle によって変換されたページ (->オリジナル) /