184 def fromui(ui, mtimepaths=None): |
182 def fromui(ui, mtimepaths=None): |
185 if mtimepaths is None: |
183 if mtimepaths is None: |
186 mtimepaths = _getmtimepaths(ui) |
184 mtimepaths = _getmtimepaths(ui) |
187 confighash = _confighash(ui) |
185 confighash = _confighash(ui) |
188 mtimehash = _mtimehash(mtimepaths) |
186 mtimehash = _mtimehash(mtimepaths) |
189 _log('confighash = %s mtimehash = %s\n' % (confighash, mtimehash)) |
187 ui.log('cmdserver', 'confighash = %s mtimehash = %s\n', |
|
188 confighash, mtimehash) |
190 return hashstate(confighash, mtimehash, mtimepaths) |
189 return hashstate(confighash, mtimehash, mtimepaths) |
191 |
190 |
192 def _newchgui(srcui, csystem, attachio): |
191 def _newchgui(srcui, csystem, attachio): |
193 class chgui(srcui.__class__): |
192 class chgui(srcui.__class__): |
194 def __init__(self, src=None): |
193 def __init__(self, src=None): |
342 """ |
340 """ |
343 # tell client to sendmsg() with 1-byte payload, which makes it |
341 # tell client to sendmsg() with 1-byte payload, which makes it |
344 # distinctive from "attachio\n" command consumed by client.read() |
342 # distinctive from "attachio\n" command consumed by client.read() |
345 self.clientsock.sendall(struct.pack('>cI', 'I', 1)) |
343 self.clientsock.sendall(struct.pack('>cI', 'I', 1)) |
346 clientfds = util.recvfds(self.clientsock.fileno()) |
344 clientfds = util.recvfds(self.clientsock.fileno()) |
347 _log('received fds: %r\n' % clientfds) |
345 self.ui.log('chgserver', 'received fds: %r\n', clientfds) |
348 |
346 |
349 ui = self.ui |
347 ui = self.ui |
350 ui.flush() |
348 ui.flush() |
351 self._saveio() |
349 self._saveio() |
352 for fd, (cn, fn, mode) in zip(clientfds, _iochannels): |
350 for fd, (cn, fn, mode) in zip(clientfds, _iochannels): |
448 if self.hashstate.mtimehash: |
446 if self.hashstate.mtimehash: |
449 insts.append('reconnect') |
447 insts.append('reconnect') |
450 if newhash.confighash != self.hashstate.confighash: |
448 if newhash.confighash != self.hashstate.confighash: |
451 addr = _hashaddress(self.baseaddress, newhash.confighash) |
449 addr = _hashaddress(self.baseaddress, newhash.confighash) |
452 insts.append('redirect %s' % addr) |
450 insts.append('redirect %s' % addr) |
453 _log('validate: %s\n' % insts) |
451 self.ui.log('chgserver', 'validate: %s\n', insts) |
454 self.cresult.write('\0'.join(insts) or '\0') |
452 self.cresult.write('\0'.join(insts) or '\0') |
455 |
453 |
456 def chdir(self): |
454 def chdir(self): |
457 """Change current directory |
455 """Change current directory |
458 |
456 |
460 It does not affect --config parameter. |
458 It does not affect --config parameter. |
461 """ |
459 """ |
462 path = self._readstr() |
460 path = self._readstr() |
463 if not path: |
461 if not path: |
464 return |
462 return |
465 _log('chdir to %r\n' % path) |
463 self.ui.log('chgserver', 'chdir to %r\n', path) |
466 os.chdir(path) |
464 os.chdir(path) |
467 |
465 |
468 def setumask(self): |
466 def setumask(self): |
469 """Change umask (DEPRECATED)""" |
467 """Change umask (DEPRECATED)""" |
470 # BUG: this does not follow the message frame structure, but kept for |
468 # BUG: this does not follow the message frame structure, but kept for |
478 raise ValueError('invalid mask length in setumask2 request') |
476 raise ValueError('invalid mask length in setumask2 request') |
479 self._setumask(data) |
477 self._setumask(data) |
480 |
478 |
481 def _setumask(self, data): |
479 def _setumask(self, data): |
482 mask = struct.unpack('>I', data)[0] |
480 mask = struct.unpack('>I', data)[0] |
483 _log('setumask %r\n' % mask) |
481 self.ui.log('chgserver', 'setumask %r\n', mask) |
484 os.umask(mask) |
482 os.umask(mask) |
485 |
483 |
486 def runcommand(self): |
484 def runcommand(self): |
487 # pager may be attached within the runcommand session, which should |
485 # pager may be attached within the runcommand session, which should |
488 # be detached at the end of the session. otherwise the pager wouldn't |
486 # be detached at the end of the session. otherwise the pager wouldn't |
503 l = self._readlist() |
501 l = self._readlist() |
504 try: |
502 try: |
505 newenv = dict(s.split('=', 1) for s in l) |
503 newenv = dict(s.split('=', 1) for s in l) |
506 except ValueError: |
504 except ValueError: |
507 raise ValueError('unexpected value in setenv request') |
505 raise ValueError('unexpected value in setenv request') |
508 _log('setenv: %r\n' % sorted(newenv.keys())) |
506 self.ui.log('chgserver', 'setenv: %r\n', sorted(newenv.keys())) |
509 encoding.environ.clear() |
507 encoding.environ.clear() |
510 encoding.environ.update(newenv) |
508 encoding.environ.update(newenv) |
511 |
509 |
512 capabilities = commandserver.server.capabilities.copy() |
510 capabilities = commandserver.server.capabilities.copy() |
513 capabilities.update({'attachio': attachio, |
511 capabilities.update({'attachio': attachio, |
519 |
517 |
520 if util.safehasattr(procutil, 'setprocname'): |
518 if util.safehasattr(procutil, 'setprocname'): |
521 def setprocname(self): |
519 def setprocname(self): |
522 """Change process title""" |
520 """Change process title""" |
523 name = self._readstr() |
521 name = self._readstr() |
524 _log('setprocname: %r\n' % name) |
522 self.ui.log('chgserver', 'setprocname: %r\n', name) |
525 procutil.setprocname(name) |
523 procutil.setprocname(name) |
526 capabilities['setprocname'] = setprocname |
524 capabilities['setprocname'] = setprocname |
527 |
525 |
528 def _tempaddress(address): |
526 def _tempaddress(address): |
529 return '%s.%d.tmp' % (address, os.getpid()) |
527 return '%s.%d.tmp' % (address, os.getpid()) |