summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjquast <contact@jeffquast.com>2014-08-24 15:06:15 -0700
committerjquast <contact@jeffquast.com>2014-08-24 15:06:15 -0700
commite2ff2f47fc7719ebf4375eec81f996362816bb10 (patch)
treeb8cdf2ee0ebf80d2a977c785eaefb085a5335cf2
parent8d96042177a6986ae5b117e31916638309b2fd03 (diff)
downloadpexpect-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__.py11
-rwxr-xr-xtests/test_expect.py37
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')