[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