[PATCH] cmdserver: add command to get pid of server handling current connection
Yuya Nishihara
yuya at tcha.org
Fri Oct 17 10:39:00 CDT 2014
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1413556690 -32400
# Fri Oct 17 23:38:10 2014 +0900
# Node ID 1b432767e0829aba65a8f63bdcdb3bb9cabbce4f
# Parent 840be5ca03e1db16ba994e55597771c418166c97
cmdserver: add command to get pid of server handling current connection
Since unix-mode server forks child process per request, client cannot know
the pid of the server, which is necessary to send SIGINT for example.
Though Linux has getsockopt(SO_PEERCRED), it cannot be used because the server
fork()s after accept(). So commandserver should provide "getpid" command.
diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -212,6 +212,9 @@ class server(object):
""" writes the current encoding to the result channel """
self.cresult.write(encoding.encoding)
+ def getpid(self):
+ self.cresult.write(struct.pack('>i', os.getpid()))
+
def serveone(self):
cmd = self.client.readline()[:-1]
if cmd:
@@ -226,7 +229,8 @@ class server(object):
return cmd != ''
capabilities = {'runcommand' : runcommand,
- 'getencoding' : getencoding}
+ 'getencoding' : getencoding,
+ 'getpid' : getpid}
def serve(self):
hellomsg = 'capabilities: ' + ' '.join(sorted(self.capabilities))
diff --git a/tests/test-commandserver.t b/tests/test-commandserver.t
--- a/tests/test-commandserver.t
+++ b/tests/test-commandserver.t
@@ -16,7 +16,7 @@
... # run an arbitrary command to make sure the next thing the server
... # sends isn't part of the hello message
... runcommand(server, ['id'])
- o, 'capabilities: getencoding runcommand\nencoding: *' (glob)
+ o, 'capabilities: getencoding getpid runcommand\nencoding: *' (glob)
*** runcommand id
000000000000 tip
@@ -519,6 +519,21 @@ check that local configs for the cached
prompt: 5678
+get pid of the server (same as subprocess' in pipe mode):
+
+ >>> import struct
+ >>> from hgclient import readchannel, check
+ >>> @check
+ ... def getpid(server):
+ ... readchannel(server)
+ ... server.stdin.write('getpid\n')
+ ... ch, data = readchannel(server)
+ ... print '%c, %r' % (ch, data)
+ ... pid, = struct.unpack('>i', data)
+ ... assert pid == server.pid
+ r, '*' (glob)
+
+
start without repository:
$ cd ..
@@ -531,7 +546,7 @@ start without repository:
... # run an arbitrary command to make sure the next thing the server
... # sends isn't part of the hello message
... runcommand(server, ['id'])
- o, 'capabilities: getencoding runcommand\nencoding: *' (glob)
+ o, 'capabilities: getencoding getpid runcommand\nencoding: *' (glob)
*** runcommand id
abort: there is no Mercurial repository here (.hg not found)
[255]
@@ -562,7 +577,7 @@ unix domain socket:
... print '%c, %r' % (ch, data)
... runcommand(conn, ['id'])
>>> check(hellomessage, server.connect)
- o, 'capabilities: getencoding runcommand\nencoding: *' (glob)
+ o, 'capabilities: getencoding getpid runcommand\nencoding: *' (glob)
*** runcommand id
eff892de26ec tip bm1/bm2/bm3
>>> def unknowncommand(conn):
More information about the Mercurial-devel
mailing list