comparison mercurial/commandserver.py @ 43077:687b865b95ad

formatting: byteify all mercurial/ and hgext/ string literals Done with python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py') black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**') # skip-blame mass-reformatting only Differential Revision: https://phab.mercurial-scm.org/D6972
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:48:39 -0400
parents 2372284d9457
children c59eb1560c44
comparison
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
51 self.out = out 51 self.out = out
52 self.channel = channel 52 self.channel = channel
53 53
54 @property 54 @property
55 def name(self): 55 def name(self):
56 return '<%c-channel>' % self.channel 56 return b'<%c-channel>' % self.channel
57 57
58 def write(self, data): 58 def write(self, data):
59 if not data: 59 if not data:
60 return 60 return
61 # single write() to guarantee the same atomicity as the underlying file 61 # single write() to guarantee the same atomicity as the underlying file
62 self.out.write(struct.pack('>cI', self.channel, len(data)) + data) 62 self.out.write(struct.pack(b'>cI', self.channel, len(data)) + data)
63 self.out.flush() 63 self.out.flush()
64 64
65 def __getattr__(self, attr): 65 def __getattr__(self, attr):
66 if attr in (r'isatty', r'fileno', r'tell', r'seek'): 66 if attr in (r'isatty', r'fileno', r'tell', r'seek'):
67 raise AttributeError(attr) 67 raise AttributeError(attr)
117 self.out = out 117 self.out = out
118 self.channel = channel 118 self.channel = channel
119 119
120 @property 120 @property
121 def name(self): 121 def name(self):
122 return '<%c-channel>' % self.channel 122 return b'<%c-channel>' % self.channel
123 123
124 def read(self, size=-1): 124 def read(self, size=-1):
125 if size < 0: 125 if size < 0:
126 # if we need to consume all the clients input, ask for 4k chunks 126 # if we need to consume all the clients input, ask for 4k chunks
127 # so the pipe doesn't fill up risking a deadlock 127 # so the pipe doesn't fill up risking a deadlock
136 else: 136 else:
137 return self._read(size, self.channel) 137 return self._read(size, self.channel)
138 138
139 def _read(self, size, channel): 139 def _read(self, size, channel):
140 if not size: 140 if not size:
141 return '' 141 return b''
142 assert size > 0 142 assert size > 0
143 143
144 # tell the client we need at most size bytes 144 # tell the client we need at most size bytes
145 self.out.write(struct.pack('>cI', channel, size)) 145 self.out.write(struct.pack(b'>cI', channel, size))
146 self.out.flush() 146 self.out.flush()
147 147
148 length = self.in_.read(4) 148 length = self.in_.read(4)
149 length = struct.unpack('>I', length)[0] 149 length = struct.unpack(b'>I', length)[0]
150 if not length: 150 if not length:
151 return '' 151 return b''
152 else: 152 else:
153 return self.in_.read(length) 153 return self.in_.read(length)
154 154
155 def readline(self, size=-1): 155 def readline(self, size=-1):
156 if size < 0: 156 if size < 0:
157 size = self.maxchunksize 157 size = self.maxchunksize
158 s = self._read(size, 'L') 158 s = self._read(size, b'L')
159 buf = s 159 buf = s
160 # keep asking for more until there's either no more or 160 # keep asking for more until there's either no more or
161 # we got a full line 161 # we got a full line
162 while s and s[-1] != '\n': 162 while s and s[-1] != b'\n':
163 s = self._read(size, 'L') 163 s = self._read(size, b'L')
164 buf += s 164 buf += s
165 165
166 return buf 166 return buf
167 else: 167 else:
168 return self._read(size, 'L') 168 return self._read(size, b'L')
169 169
170 def __iter__(self): 170 def __iter__(self):
171 return self 171 return self
172 172
173 def next(self): 173 def next(self):
219 else: 219 else:
220 self.ui = ui 220 self.ui = ui
221 self.repo = self.repoui = None 221 self.repo = self.repoui = None
222 self._prereposetups = prereposetups 222 self._prereposetups = prereposetups
223 223
224 self.cdebug = channeledoutput(fout, 'd') 224 self.cdebug = channeledoutput(fout, b'd')
225 self.cerr = channeledoutput(fout, 'e') 225 self.cerr = channeledoutput(fout, b'e')
226 self.cout = channeledoutput(fout, 'o') 226 self.cout = channeledoutput(fout, b'o')
227 self.cin = channeledinput(fin, fout, 'I') 227 self.cin = channeledinput(fin, fout, b'I')
228 self.cresult = channeledoutput(fout, 'r') 228 self.cresult = channeledoutput(fout, b'r')
229 229
230 if self.ui.config(b'cmdserver', b'log') == b'-': 230 if self.ui.config(b'cmdserver', b'log') == b'-':
231 # switch log stream of server's ui to the 'd' (debug) channel 231 # switch log stream of server's ui to the 'd' (debug) channel
232 # (don't touch repo.ui as its lifetime is longer than the server) 232 # (don't touch repo.ui as its lifetime is longer than the server)
233 self.ui = self.ui.copy() 233 self.ui = self.ui.copy()
246 def cleanup(self): 246 def cleanup(self):
247 """release and restore resources taken during server session""" 247 """release and restore resources taken during server session"""
248 248
249 def _read(self, size): 249 def _read(self, size):
250 if not size: 250 if not size:
251 return '' 251 return b''
252 252
253 data = self.client.read(size) 253 data = self.client.read(size)
254 254
255 # is the other end closed? 255 # is the other end closed?
256 if not data: 256 if not data:
262 """read a string from the channel 262 """read a string from the channel
263 263
264 format: 264 format:
265 data length (uint32), data 265 data length (uint32), data
266 """ 266 """
267 length = struct.unpack('>I', self._read(4))[0] 267 length = struct.unpack(b'>I', self._read(4))[0]
268 if not length: 268 if not length:
269 return '' 269 return b''
270 return self._read(length) 270 return self._read(length)
271 271
272 def _readlist(self): 272 def _readlist(self):
273 """read a list of NULL separated strings from the channel""" 273 """read a list of NULL separated strings from the channel"""
274 s = self._readstr() 274 s = self._readstr()
275 if s: 275 if s:
276 return s.split('\0') 276 return s.split(b'\0')
277 else: 277 else:
278 return [] 278 return []
279 279
280 def runcommand(self): 280 def runcommand(self):
281 """ reads a list of \0 terminated arguments, executes 281 """ reads a list of \0 terminated arguments, executes
300 for ui in uis: 300 for ui in uis:
301 ui.resetstate() 301 ui.resetstate()
302 # any kind of interaction must use server channels, but chg may 302 # any kind of interaction must use server channels, but chg may
303 # replace channels by fully functional tty files. so nontty is 303 # replace channels by fully functional tty files. so nontty is
304 # enforced only if cin is a channel. 304 # enforced only if cin is a channel.
305 if not util.safehasattr(self.cin, 'fileno'): 305 if not util.safehasattr(self.cin, b'fileno'):
306 ui.setconfig('ui', 'nontty', 'true', 'commandserver') 306 ui.setconfig(b'ui', b'nontty', b'true', b'commandserver')
307 307
308 req = dispatch.request( 308 req = dispatch.request(
309 args[:], 309 args[:],
310 copiedui, 310 copiedui,
311 self.repo, 311 self.repo,
316 prereposetups=self._prereposetups, 316 prereposetups=self._prereposetups,
317 ) 317 )
318 318
319 try: 319 try:
320 ret = dispatch.dispatch(req) & 255 320 ret = dispatch.dispatch(req) & 255
321 self.cresult.write(struct.pack('>i', int(ret))) 321 self.cresult.write(struct.pack(b'>i', int(ret)))
322 finally: 322 finally:
323 # restore old cwd 323 # restore old cwd
324 if '--cwd' in args: 324 if b'--cwd' in args:
325 os.chdir(self.cwd) 325 os.chdir(self.cwd)
326 326
327 def getencoding(self): 327 def getencoding(self):
328 """ writes the current encoding to the result channel """ 328 """ writes the current encoding to the result channel """
329 self.cresult.write(encoding.encoding) 329 self.cresult.write(encoding.encoding)
335 if handler: 335 if handler:
336 handler(self) 336 handler(self)
337 else: 337 else:
338 # clients are expected to check what commands are supported by 338 # clients are expected to check what commands are supported by
339 # looking at the servers capabilities 339 # looking at the servers capabilities
340 raise error.Abort(_('unknown command %s') % cmd) 340 raise error.Abort(_(b'unknown command %s') % cmd)
341 341
342 return cmd != '' 342 return cmd != b''
343 343
344 capabilities = {'runcommand': runcommand, 'getencoding': getencoding} 344 capabilities = {b'runcommand': runcommand, b'getencoding': getencoding}
345 345
346 def serve(self): 346 def serve(self):
347 hellomsg = 'capabilities: ' + ' '.join(sorted(self.capabilities)) 347 hellomsg = b'capabilities: ' + b' '.join(sorted(self.capabilities))
348 hellomsg += '\n' 348 hellomsg += b'\n'
349 hellomsg += 'encoding: ' + encoding.encoding 349 hellomsg += b'encoding: ' + encoding.encoding
350 hellomsg += '\n' 350 hellomsg += b'\n'
351 if self.cmsg: 351 if self.cmsg:
352 hellomsg += 'message-encoding: %s\n' % self.cmsg.encoding 352 hellomsg += b'message-encoding: %s\n' % self.cmsg.encoding
353 hellomsg += 'pid: %d' % procutil.getpid() 353 hellomsg += b'pid: %d' % procutil.getpid()
354 if util.safehasattr(os, 'getpgid'): 354 if util.safehasattr(os, b'getpgid'):
355 hellomsg += '\n' 355 hellomsg += b'\n'
356 hellomsg += 'pgid: %d' % os.getpgid(0) 356 hellomsg += b'pgid: %d' % os.getpgid(0)
357 357
358 # write the hello msg in -one- chunk 358 # write the hello msg in -one- chunk
359 self.cout.write(hellomsg) 359 self.cout.write(hellomsg)
360 360
361 try: 361 try:
457 try: 457 try:
458 sv.serve() 458 sv.serve()
459 # handle exceptions that may be raised by command server. most of 459 # handle exceptions that may be raised by command server. most of
460 # known exceptions are caught by dispatch. 460 # known exceptions are caught by dispatch.
461 except error.Abort as inst: 461 except error.Abort as inst:
462 ui.error(_('abort: %s\n') % inst) 462 ui.error(_(b'abort: %s\n') % inst)
463 except IOError as inst: 463 except IOError as inst:
464 if inst.errno != errno.EPIPE: 464 if inst.errno != errno.EPIPE:
465 raise 465 raise
466 except KeyboardInterrupt: 466 except KeyboardInterrupt:
467 pass 467 pass
471 # also write traceback to error channel. otherwise client cannot 471 # also write traceback to error channel. otherwise client cannot
472 # see it because it is written to server's stderr by default. 472 # see it because it is written to server's stderr by default.
473 if sv: 473 if sv:
474 cerr = sv.cerr 474 cerr = sv.cerr
475 else: 475 else:
476 cerr = channeledoutput(fout, 'e') 476 cerr = channeledoutput(fout, b'e')
477 cerr.write(encoding.strtolocal(traceback.format_exc())) 477 cerr.write(encoding.strtolocal(traceback.format_exc()))
478 raise 478 raise
479 finally: 479 finally:
480 fin.close() 480 fin.close()
481 try: 481 try:
498 self.ui = ui 498 self.ui = ui
499 499
500 def bindsocket(self, sock, address): 500 def bindsocket(self, sock, address):
501 util.bindunixsocket(sock, address) 501 util.bindunixsocket(sock, address)
502 sock.listen(socket.SOMAXCONN) 502 sock.listen(socket.SOMAXCONN)
503 self.ui.status(_('listening at %s\n') % address) 503 self.ui.status(_(b'listening at %s\n') % address)
504 self.ui.flush() # avoid buffering of status message 504 self.ui.flush() # avoid buffering of status message
505 505
506 def unlinksocket(self, address): 506 def unlinksocket(self, address):
507 os.unlink(address) 507 os.unlink(address)
508 508
525 """ 525 """
526 526
527 def __init__(self, ui, repo, opts, handler=None): 527 def __init__(self, ui, repo, opts, handler=None):
528 self.ui = ui 528 self.ui = ui
529 self.repo = repo 529 self.repo = repo
530 self.address = opts['address'] 530 self.address = opts[b'address']
531 if not util.safehasattr(socket, 'AF_UNIX'): 531 if not util.safehasattr(socket, b'AF_UNIX'):
532 raise error.Abort(_('unsupported platform')) 532 raise error.Abort(_(b'unsupported platform'))
533 if not self.address: 533 if not self.address:
534 raise error.Abort(_('no socket path specified with --address')) 534 raise error.Abort(_(b'no socket path specified with --address'))
535 self._servicehandler = handler or unixservicehandler(ui) 535 self._servicehandler = handler or unixservicehandler(ui)
536 self._sock = None 536 self._sock = None
537 self._mainipc = None 537 self._mainipc = None
538 self._workeripc = None 538 self._workeripc = None
539 self._oldsigchldhandler = None 539 self._oldsigchldhandler = None
540 self._workerpids = set() # updated by signal handler; do not iterate 540 self._workerpids = set() # updated by signal handler; do not iterate
541 self._socketunlinked = None 541 self._socketunlinked = None
542 # experimental config: cmdserver.max-repo-cache 542 # experimental config: cmdserver.max-repo-cache
543 maxlen = ui.configint(b'cmdserver', b'max-repo-cache') 543 maxlen = ui.configint(b'cmdserver', b'max-repo-cache')
544 if maxlen < 0: 544 if maxlen < 0:
545 raise error.Abort(_('negative max-repo-cache size not allowed')) 545 raise error.Abort(_(b'negative max-repo-cache size not allowed'))
546 self._repoloader = repocache.repoloader(ui, maxlen) 546 self._repoloader = repocache.repoloader(ui, maxlen)
547 547
548 def init(self): 548 def init(self):
549 self._sock = socket.socket(socket.AF_UNIX) 549 self._sock = socket.socket(socket.AF_UNIX)
550 # IPC channel from many workers to one main process; this is actually 550 # IPC channel from many workers to one main process; this is actually
551 # a uni-directional pipe, but is backed by a DGRAM socket so each 551 # a uni-directional pipe, but is backed by a DGRAM socket so each
552 # message can be easily separated. 552 # message can be easily separated.
553 o = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM) 553 o = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)
554 self._mainipc, self._workeripc = o 554 self._mainipc, self._workeripc = o
555 self._servicehandler.bindsocket(self._sock, self.address) 555 self._servicehandler.bindsocket(self._sock, self.address)
556 if util.safehasattr(procutil, 'unblocksignal'): 556 if util.safehasattr(procutil, b'unblocksignal'):
557 procutil.unblocksignal(signal.SIGCHLD) 557 procutil.unblocksignal(signal.SIGCHLD)
558 o = signal.signal(signal.SIGCHLD, self._sigchldhandler) 558 o = signal.signal(signal.SIGCHLD, self._sigchldhandler)
559 self._oldsigchldhandler = o 559 self._oldsigchldhandler = o
560 self._socketunlinked = False 560 self._socketunlinked = False
561 self._repoloader.start() 561 self._repoloader.start()