~forest-bond/pshell/dev

« back to all changes in this revision

Viewing changes to pshell/shell.py

  • Committer: forest.bond at rapidrollout
  • Date: 2010-11-09 01:43:23 UTC
  • Revision ID: forest.bond@rapidrollout.com-20101109014323-ddan8vnhzxv6ngf7
Shell: Override Pexpect's implementations of methods read and write to get
faster/more correct behavior.

Show diffs side-by-side

added added

removed removed

Lines of Context:
411
411
            status = self._check_last_status(output)
412
412
            return status, output
413
413
 
 
414
    # Override read for better performance in the case where a known number of
 
415
    # bytes are being read.  Pexpect uses a regular expression to implement
 
416
    # this, which is bound to be slow when reading a significant amount of
 
417
    # data.
 
418
 
 
419
    def read(self, size = -1):
 
420
        if size < 0:
 
421
            # We don't bother handling the read-until-EOF case.  Anybody doing
 
422
            # that doesn't care about read performance, which is the reason
 
423
            # we're overriding the parent implementation, anyway.
 
424
            return super(Shell, self).read(size)
 
425
 
 
426
        nbytes = 0
 
427
        parts = []
 
428
        while True:
 
429
            s = os.read(self.child_fd, size - nbytes)
 
430
            if not s:
 
431
                break
 
432
 
 
433
            nbytes += len(s)
 
434
            parts.append(s)
 
435
 
 
436
            if nbytes >= size:
 
437
                break
 
438
 
 
439
        return ''.join(parts)
 
440
 
 
441
    # FIXME: The broken behavior mentioned below would also affect send.
 
442
 
 
443
    # Override write to get correct behavior.  Pexpect does not correctly
 
444
    # handle the situation where only part of the string is written.  This will
 
445
    # likely only be an issue when the write is interrupted by a signal, in
 
446
    # which case Pexpect would only write part of the string and then return.
 
447
 
 
448
    def write(self, s):
 
449
        if isinstance(s, unicode):
 
450
            s = str(s)
 
451
 
 
452
        nbytes = 0
 
453
        while True:
 
454
            nbytes += os.write(self.child_fd, s[nbytes:])
 
455
            if nbytes >= len(s):
 
456
                return
 
457
 
414
458
    def encode(self, s):
415
459
        return s.encode(self.shell_encoding)
416
460