Eryk Sun <eryk...@gmail.com> added the comment: Note that the CRT checks at startup whether an inherited FD is valid by calling GetFileType. If the handle is invalid or not a File, then the FD effectively is not inherited. This doesn't completely avoid the problem, since there's still a chance the handle was already assigned to a File at startup. Also, it has to skip this check if the FD is flagged as a pipe, because a pipe is likely opened in synchronous mode and blocked on a read in the parent, in which case calling GetFileType would deadlock.
For example: >>> os.pipe() (3, 4) >>> os.dup2(4, 5, False) # fd 5 is still inheritable >>> os.spawnl(os.P_WAIT, sys.executable, 'python') Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import os, msvcrt >>> msvcrt.get_osfhandle(5) 420 Handle 420 was not inherited, so it may be unassigned, or it could be for some random kernel object. It's assigned in this case: >>> os.get_handle_inheritable(420) False I have a function that calls NtQueryObject to get the type name for a kernel handle: >>> get_type_name(420) 'Semaphore' Now, let's model what could be a confusing bug for someone using this semaphore: >>> os.close(5) # BUGBUG >>> os.get_handle_inheritable(420) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [WinError 6] The handle is invalid ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue32865> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com