Eryk Sun <eryk...@gmail.com> added the comment:
> It sounds like we should probably revert to the middle ground, and > skip _raising the error_ if _Py_set_inheritable for files of type > FILE_TYPE_CHAR. The problem is just console pseudohandles in Windows 7 and earlier. Maybe it should just check for this case before calling SetHandleInformation. For example: /* This check can be removed once support for Windows 7 ends. */ #define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \ GetFileType(handle) == FILE_TYPE_CHAR) if (!CONSOLE_PSEUDOHANDLE(handle) && !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) { if (raise) PyErr_SetFromWindowsErr(0); return -1; } We have similar Python code in subprocess Popen._filter_handle_list, which filters out console pseudohandles because they don't work with PROC_THREAD_ATTRIBUTE_HANDLE_LIST. A similar check could be added to os_set_handle_inheritable_impl in Modules/posixmodule.c. > As Victor pointed out, the docs already call out the special case in > Windows. For os.dup it says On Windows, when duplicating a standard stream (0: stdin, 1: stdout, 2: stderr), the new file descriptor is inheritable. The standard handles aren't relevant. Also, under "inheritance of file descriptors", it says: On Windows, non-inheritable handles and file descriptors are closed in child processes, except for standard streams (file descriptors 0, 1 and 2: stdin, stdout and stderr), which are always inherited. The standard handles aren't always inherited. If bInheritHandles is TRUE (i.e. close_fds=False), a standard handle has to be iheritable for it to be inherited. For example, in Windows 10, make stderr (a ConDrv console handle) non-inheritable and create a child process with close_fds=False: >>> os.set_handle_inheritable(msvcrt.get_osfhandle(2), False) >>> cmd = 'import sys; print(sys.stderr)' >>> subprocess.call(f'python.exe -c "{cmd}"', close_fds=False) None 0 In Windows 7 and earlier, it seems that inheritable console pseudohandles are always inherited, regardless of bInheritHandles -- as long as the child process attaches to the parent's console. SetHandleInformation isn't supported for console pseudohandles, but the inheritable flag is still set or cleared when a console pseudohandle is created via CreateConsoleScreenBuffer, CreateFileW (routed to OpenConsoleW), and DuplicateHandle (routed to DuplicateConsoleHandle). It's worth mentioning that the system sometimes duplicates (not inherits) standard handles to a child process. A simple example in Windows 10 would be subprocess.call('python.exe'). All of the follow requirements must be satisfied for CreateProcessW to duplicate a standard handle to a child: * it's not a console pseudohandle (e.g. it's a ConDrv console handle in Windows 8+, or handle for the NUL device, a pipe, or disk file) * the target executable is a console application (e.g. python.exe, not pythonw.exe) * handle inheritance is disabled (i.e. bInheritHandles is FALSE) * the startup-info standard handles aren't used (i.e. STARTF_USESTDHANDLES isn't set) * the call isn't flagged to execute without a console or to allocate a new console (i.e. no DETACHED_PROCESS, CREATE_NEW_CONSOLE, or CREATE_NO_WINDOW) In this case, CreateProcessW also has to update the handle value in the child since generally the duplicate has a new value. With inheritance, in contrast, the handle value is the same in the parent and child. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue37549> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com