Submitter | via Mercurial-devel |
---|---|
Date | July 4, 2018, 12:20 p.m. |
Message ID | <3a0f322af1926e52322d.1530706826@firefly.edlund.dk> |
Download | mbox | patch |
Permalink | /patch/32613/ |
State | Accepted |
Headers | show |
Comments
Any comments? I am not really satisfied with the name "lasterrorwaspipeerror", but I couldn't find anything better. I also don't know if we want that in flush, but it seems it would be correct. The original code is many years old, so I'm not sure anyone remembers. I tried to find a way to extract the windows errorcode from an IOError, but that doesn't seem possible. Once it's mapped, I suppose it's discarded. The current method assumes that it's still valid, which isn't 100% satisfying somehow. We could also go for the simpler solution and simply detect EINVAL, but that might misdetect in some cases. We can also put it on default if you aren't comfortable with it on stable, but it _is_ a regression of sorts, at least from when the pager wasn't in core. The last version I tested (where I don't see it) is 4.0.1. -- Sune
On Wed, 04 Jul 2018 14:20:26 +0200, Sune Foldager via Mercurial-devel wrote: > # HG changeset patch > # User Sune Foldager <cryo@cyanite.org> > # Date 1530706753 -7200 > # Wed Jul 04 14:19:13 2018 +0200 > # Branch stable > # Node ID 3a0f322af1926e52322d2cff90a71529f359f2d9 > # Parent 173cfdde0c8611fd86d26c0467b42aabf03bda0f > windows: fix incorrect detection of broken pipe when writing to pager Queued for stable, thanks. > I tried to find a way to extract the windows errorcode from an IOError, > but that doesn't seem possible. Once it's mapped, I suppose it's discarded. Perhaps there's no way to. IOError would be directly mapped from the errno value of the libc layer.
Patch
diff --git a/mercurial/win32.py b/mercurial/win32.py --- a/mercurial/win32.py +++ b/mercurial/win32.py @@ -44,6 +44,7 @@ from . import ( _ERROR_INVALID_PARAMETER = 87 _ERROR_BROKEN_PIPE = 109 _ERROR_INSUFFICIENT_BUFFER = 122 +_ERROR_NO_DATA = 232 # WPARAM is defined as UINT_PTR (unsigned type) # LPARAM is defined as LONG_PTR (signed type) @@ -406,6 +407,12 @@ def peekpipe(pipe): return avail.value +def lasterrorwaspipeerror(err): + if err.errno != errno.EINVAL: + return False + err = _kernel32.GetLastError() + return err == _ERROR_BROKEN_PIPE or err == _ERROR_NO_DATA + def testpid(pid): '''return True if pid is still running or unable to determine, False otherwise''' diff --git a/mercurial/windows.py b/mercurial/windows.py --- a/mercurial/windows.py +++ b/mercurial/windows.py @@ -172,7 +172,7 @@ class winstdout(object): self.fp.write(s[start:end]) start = end except IOError as inst: - if inst.errno != 0: + if inst.errno != 0 and not win32.lasterrorwaspipeerror(inst): raise self.close() raise IOError(errno.EPIPE, 'Broken pipe') @@ -181,7 +181,7 @@ class winstdout(object): try: return self.fp.flush() except IOError as inst: - if inst.errno != errno.EINVAL: + if not win32.lasterrorwaspipeerror(inst): raise raise IOError(errno.EPIPE, 'Broken pipe')