Message333814
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 |
|
Date |
User |
Action |
Args |
2019-01-17 01:57:20 | eryksun | set | recipients:
+ eryksun, jimbo1qaz_ |
2019-01-17 01:57:18 | eryksun | set | messageid: <1547690238.43.0.491477605043.issue35754@roundup.psfhosted.org> |
2019-01-17 01:57:18 | eryksun | link | issue35754 messages |
2019-01-17 01:57:18 | eryksun | create | |
|