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 |