diff options
author | jquast <contact@jeffquast.com> | 2014-08-24 15:06:15 -0700 |
---|---|---|
committer | jquast <contact@jeffquast.com> | 2014-08-24 15:06:15 -0700 |
commit | e2ff2f47fc7719ebf4375eec81f996362816bb10 (patch) | |
tree | b8cdf2ee0ebf80d2a977c785eaefb085a5335cf2 | |
parent | 8d96042177a6986ae5b117e31916638309b2fd03 (diff) | |
download | pexpect-e2ff2f47fc7719ebf4375eec81f996362816bb10.tar.gz |
Closes issue #86 and issue #100
Fallback to using stdout, and, when both stdin
and stdout are *both* closed, catch ValueError
and use the same constants as when the attached
process is not a terminal.
-rw-r--r-- | pexpect/__init__.py | 11 | ||||
-rwxr-xr-x | tests/test_expect.py | 37 |
2 files changed, 44 insertions, 4 deletions
diff --git a/pexpect/__init__.py b/pexpect/__init__.py index 4a34f15..06dbac4 100644 --- a/pexpect/__init__.py +++ b/pexpect/__init__.py @@ -498,12 +498,17 @@ class spawn(object): # inherit EOF and INTR definitions from controlling process. try: from termios import VEOF, VINTR - fd = sys.__stdin__.fileno() + try: + fd = sys.__stdin__.fileno() + except ValueError: + # ValueError: I/O operation on closed file + fd = sys.__stdout__.fileno() self._INTR = ord(termios.tcgetattr(fd)[6][VINTR]) self._EOF = ord(termios.tcgetattr(fd)[6][VEOF]) - except (ImportError, OSError, IOError, termios.error): + except (ImportError, OSError, IOError, ValueError, termios.error): # unless the controlling process is also not a terminal, - # such as cron(1). Fall-back to using CEOF and CINTR. + # such as cron(1), or when stdin and stdout are both closed. + # Fall-back to using CEOF and CINTR. There try: from termios import CEOF, CINTR (self._INTR, self._EOF) = (CINTR, CEOF) diff --git a/tests/test_expect.py b/tests/test_expect.py index 8ccb9c5..3f4c9d8 100755 --- a/tests/test_expect.py +++ b/tests/test_expect.py @@ -18,11 +18,13 @@ PEXPECT LICENSE OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ''' +import multiprocessing import unittest import subprocess import time import signal import sys +import os import pexpect from . import PexpectTestCase @@ -542,7 +544,40 @@ class ExpectTestCase (PexpectTestCase.PexpectTestCase): signal.alarm(1) p1.expect('END') + def test_stdin_closed(self): + ''' + Ensure pexpect continues to operate even when stdin is closed + ''' + class Closed_stdin_proc(multiprocessing.Process): + def run(self): + sys.__stdin__.close() + cat = pexpect.spawn('cat') + cat.sendeof() + cat.expect(pexpect.EOF) + + proc = Closed_stdin_proc() + proc.start() + proc.join() + assert proc.exitcode == 0 + + def test_stdin_stdout_closed(self): + ''' + Ensure pexpect continues to operate even when stdin and stdout is closed + ''' + class Closed_stdin_stdout_proc(multiprocessing.Process): + def run(self): + sys.__stdin__.close() + sys.__stdout__.close() + cat = pexpect.spawn('cat') + cat.sendeof() + cat.expect(pexpect.EOF) + + proc = Closed_stdin_stdout_proc() + proc.start() + proc.join() + assert proc.exitcode == 0 + if __name__ == '__main__': unittest.main() -suite = unittest.makeSuite(ExpectTestCase,'test') +suite = unittest.makeSuite(ExpectTestCase, 'test') |