mercurial/commandserver.py
changeset 23324 69f86b937035
parent 23323 bc374458688b
child 25660 328739ea70c3
equal deleted inserted replaced
23323:bc374458688b 23324:69f86b937035
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     7 
     7 
     8 from i18n import _
     8 from i18n import _
     9 import struct
     9 import struct
    10 import os, errno, traceback, SocketServer
    10 import sys, os, errno, traceback, SocketServer
    11 import dispatch, encoding, util
    11 import dispatch, encoding, util
    12 
    12 
    13 logfile = None
    13 logfile = None
    14 
    14 
    15 def log(*args):
    15 def log(*args):
   246             # its request
   246             # its request
   247             return 1
   247             return 1
   248 
   248 
   249         return 0
   249         return 0
   250 
   250 
       
   251 def _protectio(ui):
       
   252     """ duplicates streams and redirect original to null if ui uses stdio """
       
   253     ui.flush()
       
   254     newfiles = []
       
   255     nullfd = os.open(os.devnull, os.O_RDWR)
       
   256     for f, sysf, mode in [(ui.fin, sys.stdin, 'rb'),
       
   257                           (ui.fout, sys.stdout, 'wb')]:
       
   258         if f is sysf:
       
   259             newfd = os.dup(f.fileno())
       
   260             os.dup2(nullfd, f.fileno())
       
   261             f = os.fdopen(newfd, mode)
       
   262         newfiles.append(f)
       
   263     os.close(nullfd)
       
   264     return tuple(newfiles)
       
   265 
       
   266 def _restoreio(ui, fin, fout):
       
   267     """ restores streams from duplicated ones """
       
   268     ui.flush()
       
   269     for f, uif in [(fin, ui.fin), (fout, ui.fout)]:
       
   270         if f is not uif:
       
   271             os.dup2(f.fileno(), uif.fileno())
       
   272             f.close()
       
   273 
   251 class pipeservice(object):
   274 class pipeservice(object):
   252     def __init__(self, ui, repo, opts):
   275     def __init__(self, ui, repo, opts):
   253         self.ui = ui
   276         self.ui = ui
   254         self.repo = repo
   277         self.repo = repo
   255 
   278 
   256     def init(self):
   279     def init(self):
   257         pass
   280         pass
   258 
   281 
   259     def run(self):
   282     def run(self):
   260         ui = self.ui
   283         ui = self.ui
   261         sv = server(ui, self.repo, ui.fin, ui.fout)
   284         # redirect stdio to null device so that broken extensions or in-process
   262         return sv.serve()
   285         # hooks will never cause corruption of channel protocol.
       
   286         fin, fout = _protectio(ui)
       
   287         try:
       
   288             sv = server(ui, self.repo, fin, fout)
       
   289             return sv.serve()
       
   290         finally:
       
   291             _restoreio(ui, fin, fout)
   263 
   292 
   264 class _requesthandler(SocketServer.StreamRequestHandler):
   293 class _requesthandler(SocketServer.StreamRequestHandler):
   265     def handle(self):
   294     def handle(self):
   266         ui = self.server.ui
   295         ui = self.server.ui
   267         repo = self.server.repo
   296         repo = self.server.repo