changeset 1609:c50bddfbc812

eliminate backtrace when piping output on windows. this fixes issue 54.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Mon, 02 Jan 2006 15:25:33 -0800
parents 722fd16f6f8c
children 84e9b3484ff6
files mercurial/ui.py mercurial/util.py
diffstat 2 files changed, 29 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -110,7 +110,7 @@ class ui(object):
             sys.stdout.write(str(a))
 
     def write_err(self, *args):
-        sys.stdout.flush()
+        if not sys.stdout.closed: sys.stdout.flush()
         for a in args:
             sys.stderr.write(str(a))
 
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -13,7 +13,8 @@ platform-specific details from the core.
 import os, errno
 from i18n import gettext as _
 from demandload import *
-demandload(globals(), "re cStringIO shutil popen2 sys tempfile threading time")
+demandload(globals(), "cStringIO errno popen2 re shutil sys tempfile")
+demandload(globals(), "threading time")
 
 def pipefilter(s, cmd):
     '''filter string S through command CMD, returning its output'''
@@ -442,12 +443,36 @@ else:
 if os.name == 'nt':
     demandload(globals(), "msvcrt")
     nulldev = 'NUL:'
-    
+
+    class winstdout:
+        '''stdout on windows misbehaves if sent through a pipe'''
+
+        def __init__(self, fp):
+            self.fp = fp
+
+        def __getattr__(self, key):
+            return getattr(self.fp, key)
+
+        def close(self):
+            try:
+                self.fp.close()
+            except: pass
+
+        def write(self, s):
+            try:
+                return self.fp.write(s)
+            except IOError, inst:
+                if inst.errno != 0: raise
+                self.close()
+                raise IOError(errno.EPIPE, 'Broken pipe')
+
+    sys.stdout = winstdout(sys.stdout)
+
     try:
         import win32api, win32process
         filename = win32process.GetModuleFileNameEx(win32api.GetCurrentProcess(), 0)
         systemrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
-        
+
     except ImportError:
         systemrc = r'c:\mercurial\mercurial.ini'
         pass