341 finally: |
341 finally: |
342 sv.cleanup() |
342 sv.cleanup() |
343 _restoreio(ui, fin, fout) |
343 _restoreio(ui, fin, fout) |
344 |
344 |
345 def _serverequest(ui, repo, conn, createcmdserver): |
345 def _serverequest(ui, repo, conn, createcmdserver): |
346 if True: # TODO: unindent |
346 # use a different process group from the master process, making this |
347 # use a different process group from the master process, making this |
347 # process pass kernel "is_current_pgrp_orphaned" check so signals like |
348 # process pass kernel "is_current_pgrp_orphaned" check so signals like |
348 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. |
349 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. |
349 os.setpgid(0, 0) |
350 os.setpgid(0, 0) |
350 # change random state otherwise forked request handlers would have a |
351 # change random state otherwise forked request handlers would have a |
351 # same state inherited from parent. |
352 # same state inherited from parent. |
352 random.seed() |
353 random.seed() |
353 |
354 |
354 fin = conn.makefile('rb') |
355 fin = conn.makefile('rb') |
355 fout = conn.makefile('wb') |
356 fout = conn.makefile('wb') |
356 sv = None |
357 sv = None |
357 try: |
|
358 sv = createcmdserver(repo, conn, fin, fout) |
358 try: |
359 try: |
359 sv = createcmdserver(repo, conn, fin, fout) |
360 sv.serve() |
360 try: |
361 # handle exceptions that may be raised by command server. most of |
361 sv.serve() |
362 # known exceptions are caught by dispatch. |
362 # handle exceptions that may be raised by command server. most of |
363 except error.Abort as inst: |
363 # known exceptions are caught by dispatch. |
364 ui.warn(_('abort: %s\n') % inst) |
364 except error.Abort as inst: |
365 except IOError as inst: |
365 ui.warn(_('abort: %s\n') % inst) |
366 if inst.errno != errno.EPIPE: |
366 except IOError as inst: |
367 raise |
367 if inst.errno != errno.EPIPE: |
368 except KeyboardInterrupt: |
368 raise |
369 pass |
369 except KeyboardInterrupt: |
|
370 pass |
|
371 finally: |
|
372 sv.cleanup() |
|
373 except: # re-raises |
|
374 # also write traceback to error channel. otherwise client cannot |
|
375 # see it because it is written to server's stderr by default. |
|
376 if sv: |
|
377 cerr = sv.cerr |
|
378 else: |
|
379 cerr = channeledoutput(fout, 'e') |
|
380 traceback.print_exc(file=cerr) |
|
381 raise |
|
382 finally: |
370 finally: |
383 fin.close() |
371 sv.cleanup() |
384 try: |
372 except: # re-raises |
385 fout.close() # implicit flush() may cause another EPIPE |
373 # also write traceback to error channel. otherwise client cannot |
386 except IOError as inst: |
374 # see it because it is written to server's stderr by default. |
387 if inst.errno != errno.EPIPE: |
375 if sv: |
388 raise |
376 cerr = sv.cerr |
389 # trigger __del__ since ForkingMixIn uses os._exit |
377 else: |
390 gc.collect() |
378 cerr = channeledoutput(fout, 'e') |
|
379 traceback.print_exc(file=cerr) |
|
380 raise |
|
381 finally: |
|
382 fin.close() |
|
383 try: |
|
384 fout.close() # implicit flush() may cause another EPIPE |
|
385 except IOError as inst: |
|
386 if inst.errno != errno.EPIPE: |
|
387 raise |
|
388 # trigger __del__ since ForkingMixIn uses os._exit |
|
389 gc.collect() |
391 |
390 |
392 class unixservicehandler(object): |
391 class unixservicehandler(object): |
393 """Set of pluggable operations for unix-mode services |
392 """Set of pluggable operations for unix-mode services |
394 |
393 |
395 Almost all methods except for createcmdserver() are called in the main |
394 Almost all methods except for createcmdserver() are called in the main |