285 |
285 |
286 if type == 'system', waits for: |
286 if type == 'system', waits for: |
287 |
287 |
288 exitcode length (unsigned int), |
288 exitcode length (unsigned int), |
289 exitcode (int) |
289 exitcode (int) |
|
290 |
|
291 if type == 'pager', repetitively waits for a command name ending with '\n' |
|
292 and executes it defined by cmdtable, or exits the loop if the command name |
|
293 is empty. |
290 """ |
294 """ |
291 def __init__(self, in_, out, channel): |
295 def __init__(self, in_, out, channel): |
292 self.in_ = in_ |
296 self.in_ = in_ |
293 self.out = out |
297 self.out = out |
294 self.channel = channel |
298 self.channel = channel |
295 |
299 |
296 def __call__(self, cmd, environ, cwd, type='system'): |
300 def __call__(self, cmd, environ, cwd=None, type='system', cmdtable=None): |
297 args = [type, util.quotecommand(cmd), os.path.abspath(cwd or '.')] |
301 args = [type, util.quotecommand(cmd), os.path.abspath(cwd or '.')] |
298 args.extend('%s=%s' % (k, v) for k, v in environ.iteritems()) |
302 args.extend('%s=%s' % (k, v) for k, v in environ.iteritems()) |
299 data = '\0'.join(args) |
303 data = '\0'.join(args) |
300 self.out.write(struct.pack('>cI', self.channel, len(data))) |
304 self.out.write(struct.pack('>cI', self.channel, len(data))) |
301 self.out.write(data) |
305 self.out.write(data) |
306 length, = struct.unpack('>I', length) |
310 length, = struct.unpack('>I', length) |
307 if length != 4: |
311 if length != 4: |
308 raise error.Abort(_('invalid response')) |
312 raise error.Abort(_('invalid response')) |
309 rc, = struct.unpack('>i', self.in_.read(4)) |
313 rc, = struct.unpack('>i', self.in_.read(4)) |
310 return rc |
314 return rc |
|
315 elif type == 'pager': |
|
316 while True: |
|
317 cmd = self.in_.readline()[:-1] |
|
318 if not cmd: |
|
319 break |
|
320 if cmdtable and cmd in cmdtable: |
|
321 _log('pager subcommand: %s' % cmd) |
|
322 cmdtable[cmd]() |
|
323 else: |
|
324 raise error.Abort(_('unexpected command: %s') % cmd) |
311 else: |
325 else: |
312 raise error.ProgrammingError('invalid S channel type: %s' % type) |
326 raise error.ProgrammingError('invalid S channel type: %s' % type) |
313 |
327 |
314 _iochannels = [ |
328 _iochannels = [ |
315 # server.ch, ui.fp, mode |
329 # server.ch, ui.fp, mode |