diff options
author | Thomas Kluyver <takowl@gmail.com> | 2014-09-04 10:44:51 -0700 |
---|---|---|
committer | Thomas Kluyver <takowl@gmail.com> | 2014-09-04 10:44:51 -0700 |
commit | ae950f0b759f5ecb5237c7366e866225373afebc (patch) | |
tree | 1820dd48592d73eacb34380ece1d1562770622ae | |
parent | 9057873f9b73d216149b78c922be19fac8e3a44c (diff) | |
parent | ca35dc774df9c79a57facf42f0fa7d73a4985a1d (diff) | |
download | pexpect-ae950f0b759f5ecb5237c7366e866225373afebc.tar.gz |
Merge pull request #109 from pexpect/issue-86-and-100-stdin-closed
Closes issue #86 and issue #100
-rw-r--r-- | doc/history.rst | 5 | ||||
-rw-r--r-- | pexpect/__init__.py | 11 | ||||
-rwxr-xr-x | tests/test_expect.py | 37 |
3 files changed, 49 insertions, 4 deletions
diff --git a/doc/history.rst b/doc/history.rst index 0da6c6e..a09f124 100644 --- a/doc/history.rst +++ b/doc/history.rst @@ -4,6 +4,11 @@ History Releases -------- +Version 3.4 +``````````` +* Fixed regression when executing pexpect with some prior releases of + the multiprocessing module where stdin has been closed (:ghissue:`86`). + Version 3.3 ``````````` 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') |