Eryk Sun <eryk...@gmail.com> added the comment:
If I'm right, we can reduce your example down as follows: import os import subprocess import time import ctypes RtlGetLastNtStatus = ctypes.WinDLL('ntdll').RtlGetLastNtStatus RtlGetLastNtStatus.restype = ctypes.c_ulong msys = os.path.normpath("C:/msys64/usr/bin") head = os.path.join(msys, "head.exe") p = subprocess.Popen(head, stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0) # head.exe reads 1 KiB. It closes stdin if it finds 10 lines. p.stdin.write(b'\n' * 1024) # If we immediately fill up the pipe again plus 1 extra byte, # i.e. 4097 bytes for the default queue size, then NPFS will # internally queue a pending IRP. We're synchronous, so the # I/O manager will wait for I/O completion. Meanwhile the child # has requested to close its end of the pipe. In this case, # NPFS will complete the pending IRP with STATUS_PIPE_BROKEN, # which maps to WinAPI ERROR_PIPE_BROKEN and C errno EPIPE. # # On the other hand, if we wait to give the child's close request # time to complete, then NPFS will fail our 4097 byte write # immediately with STATUS_PIPE_CLOSING, which maps to WinAPI # ERROR_NO_DATA and C errno EINVAL. time.sleep(0.0) # STATUS_PIPE_BROKEN / ERROR_PIPE_BROKEN / EPIPE #time.sleep(0.5) # STATUS_PIPE_CLOSING / ERROR_NO_DATA / EINVAL try: p.stdin.write(b'\n' * 4097) except OSError: ntstatus = RtlGetLastNtStatus() if ntstatus == 0xC000_00B1: print('NT Status: STATUS_PIPE_CLOSING\n') elif ntstatus == 0xC000_014B: print('NT Status: STATUS_PIPE_BROKEN\n') else: print('NT Status: {}\n'.format(ntstatus, '#010x')) raise This could be addressed by improving our exception handling to look at the C runtime's _doserrno [1] value for EINVAL errors, in order to map ERROR_NO_DATA to EPIPE instead of EINVAL. Only two NT status codes are mapped to ERROR_NO_DATA, and both are pipe related (STATUS_PIPE_CLOSING and STATUS_PIPE_EMPTY), so using EPIPE should be fine. [1]: https://docs.microsoft.com/en-us/cpp/c-runtime-library/errno-doserrno-sys-errlist-and-sys-nerr?view=vs-2017 ---------- nosy: +eryksun _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue35754> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com