Mercurial > hg
comparison mercurial/win32.py @ 38533:3a0f322af192 stable
windows: fix incorrect detection of broken pipe when writing to pager
Paging e.g. hg incoming on Windows and quitting the pager before the
output is consumed will print 'abort: Invalid argument'. This is
because the windows error 0xE8 (ERROR_NO_DATA) is mapped to EINVAL
even though it is documented as 'The pipe is being closed'.
Note that this fix assumes that Windows' last error code is still
valid in the exception handler. It works correctly in all my tests.
A simpler fix would be to just map EINVAL to EPIPE, like was done is
flush previously, but that would be less precise.
This error was not observed previously, when pager was an extension.
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Wed, 04 Jul 2018 14:19:13 +0200 |
parents | ed30934165c9 |
children | e7aa113b14f7 |
comparison
equal
deleted
inserted
replaced
38524:173cfdde0c86 | 38533:3a0f322af192 |
---|---|
42 _ERROR_SUCCESS = 0 | 42 _ERROR_SUCCESS = 0 |
43 _ERROR_NO_MORE_FILES = 18 | 43 _ERROR_NO_MORE_FILES = 18 |
44 _ERROR_INVALID_PARAMETER = 87 | 44 _ERROR_INVALID_PARAMETER = 87 |
45 _ERROR_BROKEN_PIPE = 109 | 45 _ERROR_BROKEN_PIPE = 109 |
46 _ERROR_INSUFFICIENT_BUFFER = 122 | 46 _ERROR_INSUFFICIENT_BUFFER = 122 |
47 _ERROR_NO_DATA = 232 | |
47 | 48 |
48 # WPARAM is defined as UINT_PTR (unsigned type) | 49 # WPARAM is defined as UINT_PTR (unsigned type) |
49 # LPARAM is defined as LONG_PTR (signed type) | 50 # LPARAM is defined as LONG_PTR (signed type) |
50 if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p): | 51 if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p): |
51 _WPARAM = ctypes.c_ulong | 52 _WPARAM = ctypes.c_ulong |
404 return 0 | 405 return 0 |
405 raise ctypes.WinError(err) | 406 raise ctypes.WinError(err) |
406 | 407 |
407 return avail.value | 408 return avail.value |
408 | 409 |
410 def lasterrorwaspipeerror(err): | |
411 if err.errno != errno.EINVAL: | |
412 return False | |
413 err = _kernel32.GetLastError() | |
414 return err == _ERROR_BROKEN_PIPE or err == _ERROR_NO_DATA | |
415 | |
409 def testpid(pid): | 416 def testpid(pid): |
410 '''return True if pid is still running or unable to | 417 '''return True if pid is still running or unable to |
411 determine, False otherwise''' | 418 determine, False otherwise''' |
412 h = _kernel32.OpenProcess(_PROCESS_QUERY_INFORMATION, False, pid) | 419 h = _kernel32.OpenProcess(_PROCESS_QUERY_INFORMATION, False, pid) |
413 if h: | 420 if h: |