Mercurial > public > mercurial-scm > hg-stable
annotate hgext/chgserver.py @ 28223:0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
This is a part of the one server per config series. In multiple-server setup,
new server may be started for a temporary config change like in command line,
--config extensions.foo=bar.py. This may end up with a lot of not so useful
server processes. Other questions are about socket file and process management,
How to stop these processes? What if a new server wants to listen on a same
address, replacing the old one?
This patch introduces AutoExitMixIn, which will:
1. Exit after being idle for too long. So useless servers won't run forever.
2. Periodically check the ownership of socket file, exit if it is no longer
owned. This brings strong consistency between the filesystem and the
process, and handles some race conditions neatly.
Since rename is atomic, a new server can just have a same server address
with an old one and won't worry about how to make sure the old server is
killed, address conflict, service downtime issues.
The user can safely stop all servers by simply removing the socket files,
without worrying about outdated or accidentally removed pidfiles.
author | Jun Wu <quark@fb.com> |
---|---|
date | Wed, 24 Feb 2016 18:42:59 +0000 |
parents | d2d04d1d2f92 |
children | 2ab59ac06b76 |
rev | line source |
---|---|
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 # chgserver.py - command server extension for cHg |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 # |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
3 # Copyright 2011 Yuya Nishihara <yuya@tcha.org> |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
4 # |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
7 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
8 """command server extension for cHg (EXPERIMENTAL) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
10 'S' channel (read/write) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
11 propagate ui.system() request to client |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
13 'attachio' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
14 attach client's stdio passed by sendmsg() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
15 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
16 'chdir' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
17 change current directory |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
18 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
19 'getpager' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 checks if pager is enabled and which pager should be executed |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 'setenv' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
23 replace os.environ completely |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
24 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
25 'SIGHUP' signal |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
26 reload configuration files |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
27 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
28 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
29 from __future__ import absolute_import |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
30 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
31 import SocketServer |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
32 import errno |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
33 import os |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
34 import re |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
35 import signal |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
36 import struct |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
37 import threading |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
38 import time |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
39 import traceback |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
40 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
41 from mercurial.i18n import _ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
42 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
43 from mercurial import ( |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
44 cmdutil, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
45 commands, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
46 commandserver, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
47 dispatch, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
48 error, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
49 osutil, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
50 util, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
51 ) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
52 |
27793
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
53 # Note for extension authors: ONLY specify testedwith = 'internal' for |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
54 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
55 # be specifying the version(s) of Mercurial they are tested with, or |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
56 # leave the attribute unspecified. |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
57 testedwith = 'internal' |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
58 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
59 _log = commandserver.log |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
61 # copied from hgext/pager.py:uisetup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
62 def _setuppagercmd(ui, options, cmd): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
63 if not ui.formatted(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
64 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
65 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
66 p = ui.config("pager", "pager", os.environ.get("PAGER")) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
67 usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
68 always = util.parsebool(options['pager']) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
69 auto = options['pager'] == 'auto' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
70 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
71 if not p: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
72 pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
73 elif always: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
74 usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
75 elif not auto: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
76 usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
77 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
78 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff'] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
79 attend = ui.configlist('pager', 'attend', attended) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
80 ignore = ui.configlist('pager', 'ignore') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
81 cmds, _ = cmdutil.findcmd(cmd, commands.table) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
82 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
83 for cmd in cmds: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
84 var = 'attend-%s' % cmd |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
85 if ui.config('pager', var): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
86 usepager = ui.configbool('pager', var) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
87 break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
88 if (cmd in attend or |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
89 (cmd not in ignore and not attend)): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
90 usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
91 break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
92 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
93 if usepager: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
94 ui.setconfig('ui', 'formatted', ui.formatted(), 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
95 ui.setconfig('ui', 'interactive', False, 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
96 return p |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
97 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
98 _envvarre = re.compile(r'\$[a-zA-Z_]+') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
99 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
100 def _clearenvaliases(cmdtable): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
101 """Remove stale command aliases referencing env vars; variable expansion |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
102 is done at dispatch.addaliases()""" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
103 for name, tab in cmdtable.items(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
104 cmddef = tab[0] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
105 if (isinstance(cmddef, dispatch.cmdalias) and |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
106 not cmddef.definition.startswith('!') and # shell alias |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
107 _envvarre.search(cmddef.definition)): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
108 del cmdtable[name] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
109 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
110 def _newchgui(srcui, csystem): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
111 class chgui(srcui.__class__): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
112 def __init__(self, src=None): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
113 super(chgui, self).__init__(src) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
114 if src: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
115 self._csystem = getattr(src, '_csystem', csystem) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
116 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
117 self._csystem = csystem |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
118 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
119 def system(self, cmd, environ=None, cwd=None, onerr=None, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
120 errprefix=None): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
121 # copied from mercurial/util.py:system() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
122 self.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
123 def py2shell(val): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
124 if val is None or val is False: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
125 return '0' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
126 if val is True: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
127 return '1' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
128 return str(val) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
129 env = os.environ.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
130 if environ: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
131 env.update((k, py2shell(v)) for k, v in environ.iteritems()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
132 env['HG'] = util.hgexecutable() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
133 rc = self._csystem(cmd, env, cwd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
134 if rc and onerr: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
135 errmsg = '%s %s' % (os.path.basename(cmd.split(None, 1)[0]), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
136 util.explainexit(rc)[0]) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
137 if errprefix: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
138 errmsg = '%s: %s' % (errprefix, errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
139 raise onerr(errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
140 return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
141 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
142 return chgui(srcui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
143 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
144 def _renewui(srcui): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
145 newui = srcui.__class__() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
146 for a in ['fin', 'fout', 'ferr', 'environ']: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
147 setattr(newui, a, getattr(srcui, a)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
148 if util.safehasattr(srcui, '_csystem'): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
149 newui._csystem = srcui._csystem |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
150 # stolen from tortoisehg.util.copydynamicconfig() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
151 for section, name, value in srcui.walkconfig(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
152 source = srcui.configsource(section, name) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
153 if ':' in source: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
154 # path:line |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
155 continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
156 if source == 'none': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
157 # ui.configsource returns 'none' by default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
158 source = '' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
159 newui.setconfig(section, name, value, source) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
160 return newui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
161 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
162 class channeledsystem(object): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
163 """Propagate ui.system() request in the following format: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
164 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
165 payload length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
166 cmd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
167 cwd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
168 envkey, '=', val, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
169 ... |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
170 envkey, '=', val |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
171 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
172 and waits: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
173 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
174 exitcode length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
175 exitcode (int) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
176 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
177 def __init__(self, in_, out, channel): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
178 self.in_ = in_ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
179 self.out = out |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
180 self.channel = channel |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
181 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
182 def __call__(self, cmd, environ, cwd): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
183 args = [util.quotecommand(cmd), cwd or '.'] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
184 args.extend('%s=%s' % (k, v) for k, v in environ.iteritems()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
185 data = '\0'.join(args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
186 self.out.write(struct.pack('>cI', self.channel, len(data))) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
187 self.out.write(data) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
188 self.out.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
189 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
190 length = self.in_.read(4) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
191 length, = struct.unpack('>I', length) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
192 if length != 4: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
193 raise error.Abort(_('invalid response')) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
194 rc, = struct.unpack('>i', self.in_.read(4)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
195 return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
196 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
197 _iochannels = [ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
198 # server.ch, ui.fp, mode |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
199 ('cin', 'fin', 'rb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
200 ('cout', 'fout', 'wb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
201 ('cerr', 'ferr', 'wb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
202 ] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
203 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
204 class chgcmdserver(commandserver.server): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
205 def __init__(self, ui, repo, fin, fout, sock): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
206 super(chgcmdserver, self).__init__( |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
207 _newchgui(ui, channeledsystem(fin, fout, 'S')), repo, fin, fout) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
208 self.clientsock = sock |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
209 self._oldios = [] # original (self.ch, ui.fp, fd) before "attachio" |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
210 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
211 def cleanup(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
212 # dispatch._runcatch() does not flush outputs if exception is not |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
213 # handled by dispatch._dispatch() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
214 self.ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
215 self._restoreio() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
216 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
217 def attachio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
218 """Attach to client's stdio passed via unix domain socket; all |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
219 channels except cresult will no longer be used |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
220 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
221 # tell client to sendmsg() with 1-byte payload, which makes it |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
222 # distinctive from "attachio\n" command consumed by client.read() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
223 self.clientsock.sendall(struct.pack('>cI', 'I', 1)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
224 clientfds = osutil.recvfds(self.clientsock.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
225 _log('received fds: %r\n' % clientfds) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
226 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
227 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
228 ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
229 first = self._saveio() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
230 for fd, (cn, fn, mode) in zip(clientfds, _iochannels): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
231 assert fd > 0 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
232 fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
233 os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
234 os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
235 if not first: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
236 continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
237 # reset buffering mode when client is first attached. as we want |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
238 # to see output immediately on pager, the mode stays unchanged |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
239 # when client re-attached. ferr is unchanged because it should |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
240 # be unbuffered no matter if it is a tty or not. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
241 if fn == 'ferr': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
242 newfp = fp |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
243 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
244 # make it line buffered explicitly because the default is |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
245 # decided on first write(), where fout could be a pager. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
246 if fp.isatty(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
247 bufsize = 1 # line buffered |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
248 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
249 bufsize = -1 # system default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
250 newfp = os.fdopen(fp.fileno(), mode, bufsize) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
251 setattr(ui, fn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
252 setattr(self, cn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
253 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
254 self.cresult.write(struct.pack('>i', len(clientfds))) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
255 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
256 def _saveio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
257 if self._oldios: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
258 return False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
259 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
260 for cn, fn, _mode in _iochannels: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
261 ch = getattr(self, cn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
262 fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
263 fd = os.dup(fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
264 self._oldios.append((ch, fp, fd)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
265 return True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
266 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
267 def _restoreio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
268 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
269 for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
270 newfp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
271 # close newfp while it's associated with client; otherwise it |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
272 # would be closed when newfp is deleted |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
273 if newfp is not fp: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
274 newfp.close() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
275 # restore original fd: fp is open again |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
276 os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
277 os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
278 setattr(self, cn, ch) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
279 setattr(ui, fn, fp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
280 del self._oldios[:] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
281 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
282 def chdir(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
283 """Change current directory |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
284 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
285 Note that the behavior of --cwd option is bit different from this. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
286 It does not affect --config parameter. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
287 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
288 path = self._readstr() |
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
289 if not path: |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
290 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
291 _log('chdir to %r\n' % path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
292 os.chdir(path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
293 |
28159 | 294 def setumask(self): |
295 """Change umask""" | |
296 mask = struct.unpack('>I', self._read(4))[0] | |
297 _log('setumask %r\n' % mask) | |
298 os.umask(mask) | |
299 | |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
300 def getpager(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
301 """Read cmdargs and write pager command to r-channel if enabled |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
302 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
303 If pager isn't enabled, this writes '\0' because channeledoutput |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
304 does not allow to write empty data. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
305 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
306 args = self._readlist() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
307 try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
308 cmd, _func, args, options, _cmdoptions = dispatch._parse(self.ui, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
309 args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
310 except (error.Abort, error.AmbiguousCommand, error.CommandError, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
311 error.UnknownCommand): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
312 cmd = None |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
313 options = {} |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
314 if not cmd or 'pager' not in options: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
315 self.cresult.write('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
316 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
317 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
318 pagercmd = _setuppagercmd(self.ui, options, cmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
319 if pagercmd: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
320 self.cresult.write(pagercmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
321 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
322 self.cresult.write('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
323 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
324 def setenv(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
325 """Clear and update os.environ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
326 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
327 Note that not all variables can make an effect on the running process. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
328 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
329 l = self._readlist() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
330 try: |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
331 newenv = dict(s.split('=', 1) for s in l) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
332 except ValueError: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
333 raise ValueError('unexpected value in setenv request') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
334 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
335 diffkeys = set(k for k in set(os.environ.keys() + newenv.keys()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
336 if os.environ.get(k) != newenv.get(k)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
337 _log('change env: %r\n' % sorted(diffkeys)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
338 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
339 os.environ.clear() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
340 os.environ.update(newenv) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
341 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
342 if set(['HGPLAIN', 'HGPLAINEXCEPT']) & diffkeys: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
343 # reload config so that ui.plain() takes effect |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
344 self.ui = _renewui(self.ui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
345 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
346 _clearenvaliases(commands.table) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
347 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
348 capabilities = commandserver.server.capabilities.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
349 capabilities.update({'attachio': attachio, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
350 'chdir': chdir, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
351 'getpager': getpager, |
28159 | 352 'setenv': setenv, |
353 'setumask': setumask}) | |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
354 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
355 # copied from mercurial/commandserver.py |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
356 class _requesthandler(SocketServer.StreamRequestHandler): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
357 def handle(self): |
28014
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
358 # use a different process group from the master process, making this |
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
359 # process pass kernel "is_current_pgrp_orphaned" check so signals like |
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
360 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. |
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
361 os.setpgid(0, 0) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
362 ui = self.server.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
363 repo = self.server.repo |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
364 sv = chgcmdserver(ui, repo, self.rfile, self.wfile, self.connection) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
365 try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
366 try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
367 sv.serve() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
368 # handle exceptions that may be raised by command server. most of |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
369 # known exceptions are caught by dispatch. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
370 except error.Abort as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
371 ui.warn(_('abort: %s\n') % inst) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
372 except IOError as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
373 if inst.errno != errno.EPIPE: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
374 raise |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
375 except KeyboardInterrupt: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
376 pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
377 finally: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
378 sv.cleanup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
379 except: # re-raises |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
380 # also write traceback to error channel. otherwise client cannot |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
381 # see it because it is written to server's stderr by default. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
382 traceback.print_exc(file=sv.cerr) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
383 raise |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
384 |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
385 def _tempaddress(address): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
386 return '%s.%d.tmp' % (address, os.getpid()) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
387 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
388 class AutoExitMixIn: # use old-style to comply with SocketServer design |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
389 lastactive = time.time() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
390 idletimeout = 3600 # default 1 hour |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
391 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
392 def startautoexitthread(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
393 # note: the auto-exit check here is cheap enough to not use a thread, |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
394 # be done in serve_forever. however SocketServer is hook-unfriendly, |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
395 # you simply cannot hook serve_forever without copying a lot of code. |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
396 # besides, serve_forever's docstring suggests using thread. |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
397 thread = threading.Thread(target=self._autoexitloop) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
398 thread.daemon = True |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
399 thread.start() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
400 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
401 def _autoexitloop(self, interval=1): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
402 while True: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
403 time.sleep(interval) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
404 if not self.issocketowner(): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
405 _log('%s is not owned, exiting.\n' % self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
406 break |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
407 if time.time() - self.lastactive > self.idletimeout: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
408 _log('being idle too long. exiting.\n') |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
409 break |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
410 self.shutdown() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
411 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
412 def process_request(self, request, address): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
413 self.lastactive = time.time() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
414 return SocketServer.ForkingMixIn.process_request( |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
415 self, request, address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
416 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
417 def server_bind(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
418 # use a unique temp address so we can stat the file and do ownership |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
419 # check later |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
420 tempaddress = _tempaddress(self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
421 self.socket.bind(tempaddress) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
422 self._socketstat = os.stat(tempaddress) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
423 # rename will replace the old socket file if exists atomically. the |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
424 # old server will detect ownership change and exit. |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
425 util.rename(tempaddress, self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
426 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
427 def issocketowner(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
428 try: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
429 stat = os.stat(self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
430 return (stat.st_ino == self._socketstat.st_ino and |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
431 stat.st_mtime == self._socketstat.st_mtime) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
432 except OSError: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
433 return False |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
434 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
435 def unlinksocketfile(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
436 if not self.issocketowner(): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
437 return |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
438 # it is possible to have a race condition here that we may |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
439 # remove another server's socket file. but that's okay |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
440 # since that server will detect and exit automatically and |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
441 # the client will start a new server on demand. |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
442 try: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
443 os.unlink(self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
444 except OSError as exc: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
445 if exc.errno != errno.ENOENT: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
446 raise |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
447 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
448 class chgunixservice(commandserver.unixservice): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
449 def init(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
450 # drop options set for "hg serve --cmdserver" command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
451 self.ui.setconfig('progress', 'assume-tty', None) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
452 signal.signal(signal.SIGHUP, self._reloadconfig) |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
453 class cls(AutoExitMixIn, SocketServer.ForkingMixIn, |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
454 SocketServer.UnixStreamServer): |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
455 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
456 repo = self.repo |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
457 self.server = cls(self.address, _requesthandler) |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
458 self.server.idletimeout = self.ui.configint( |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
459 'chgserver', 'idletimeout', self.server.idletimeout) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
460 self.server.startautoexitthread() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
461 # avoid writing "listening at" message to stdout before attachio |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
462 # request, which calls setvbuf() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
463 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
464 def _reloadconfig(self, signum, frame): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
465 self.ui = self.server.ui = _renewui(self.ui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
466 |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
467 def run(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
468 try: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
469 self.server.serve_forever() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
470 finally: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
471 self.server.unlinksocketfile() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
472 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
473 def uisetup(ui): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
474 commandserver._servicemap['chgunix'] = chgunixservice |