PEP 446: add a new "Only Inherit Some Handles on Windows" section

This commit is contained in:
Victor Stinner 2013-08-19 22:20:41 +02:00
parent 72cd6ad47a
commit b88843f02b
1 changed files with 51 additions and 2 deletions

View File

@ -83,12 +83,61 @@ See also:
* `Handle Inheritance
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms724466%28v=vs.85%29.aspx>`_
* `Q315939: PRB: Child Inherits Unintended Handles During
CreateProcess Call <http://support.microsoft.com/kb/315939/en-us>`_
* `Stackoverflow: Can TCP SOCKET handles be set not inheritable?
<http://stackoverflow.com/questions/12058911/can-tcp-socket-handles-be-set-not-inheritable>`_
Only Inherit Some Handles on Windows
------------------------------------
Since Windows Vista, ``CreateProcess()`` supports an extension of the
STARTUPINFO struture: the `STARTUPINFOEX structure
<http://msdn.microsoft.com/en-us/library/ms686329%28v=vs.85%29.aspx>`_.
Using this new structure, it is possible to specify a list of handles to
inherit: ``PROC_THREAD_ATTRIBUTE_HANDLE_LIST``. Read `Programmatically
controlling which handles are inherited by new processes in Win32
<http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx>`_
(Raymond Chen, Dec 2011) for more information.
Before Windows Vista, it is possible to make handles inheritable and
call ``CreateProcess()`` with ``bInheritHandles=TRUE``. This option
works if all other handles are non-inheritable. There is a race
condition: if another thread calls ``CreateProcess()`` with
``bInheritHandles=TRUE``, handles will also be inherited in the second
process.
Microsoft suggests to use a lock to avoid the race condition: read
`Q315939: PRB: Child Inherits Unintended Handles During CreateProcess
Call <http://support.microsoft.com/kb/315939/en-us>`_ (last review:
November 2006). The `Python issue #16500 "Add an atfork module"
<http://bugs.python.org/issue16500>`_ proposes to add such lock, it can
be used to make handles non-inheritable without the race condition. Such
lock only protects against a race condition between Python threads, C
threads are not protected.
Another option is to duplicate handles that must be inherited, pass the
number of the duplicated handles to the child process, so the child
process can steal duplicated handles using `DuplicateHandle()
<http://msdn.microsoft.com/en-us/library/windows/apps/ms724251%28v=vs.85%29.aspx>`_
with ``DUPLICATE_CLOSE_SOURCE``. Handle numbers change between the
parent and the child process because the handles are duplicated (twice),
the parent and/or the child process may be adapted to handle this
change. If the child program cannot be modified, an intermediate program
can be used to steal handles from the parent process before spawning the
final child program. The intermediate has to pass the handle of the
child process to the parent process. The parent may have to close
duplicated handles if all handles were not stolen, if the intermediate
process failed for example. If the command line is used to pass the
handle numbers, the command line must be modified when handle are
duplicated, because their number are modified.
This PEP does not include a solution to this problem because there is no
perfect solution working on all Windows versions. This point is deferred
until use cases relying on handle or file descriptor inheritance on
Windows are well known to choose the best solution, and test carefully
the implementation.
Inheritance of File Descriptors on UNIX
---------------------------------------