summaryrefslogtreecommitdiffstats
path: root/pym/portage/util/_pty.py
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2011-12-22 13:34:17 -0800
committerZac Medico <zmedico@gentoo.org>2011-12-22 13:34:17 -0800
commit22be2988af6d8425d5c4cf66d92b8b8657bdbc5a (patch)
treee6affd4671fdb05a390a2369a2b4acd57876c908 /pym/portage/util/_pty.py
parent9ef18c2a97bee1ff94163b77573aea72d7a3b01b (diff)
downloadportage-22be2988af6d8425d5c4cf66d92b8b8657bdbc5a.tar.gz
portage-22be2988af6d8425d5c4cf66d92b8b8657bdbc5a.tar.bz2
portage-22be2988af6d8425d5c4cf66d92b8b8657bdbc5a.zip
_pty.py: remove _test_pty_eof()
If array.fromfile() is not used, then _test_pty_eof() is useless. This function was for runtime detection of python issue 5380: http://bugs.python.org/issue5380 However, array.fromfile() use has since been abandoned due to bugs that exist in all known versions of Python (including Python 2.7 and Python 3.2). See PipeReaderArrayTestCase, for example.
Diffstat (limited to 'pym/portage/util/_pty.py')
-rw-r--r--pym/portage/util/_pty.py157
1 files changed, 8 insertions, 149 deletions
diff --git a/pym/portage/util/_pty.py b/pym/portage/util/_pty.py
index 97a38c0c3..efabb0a0d 100644
--- a/pym/portage/util/_pty.py
+++ b/pym/portage/util/_pty.py
@@ -1,154 +1,23 @@
# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import errno
-import fcntl
import platform
import pty
-import select
-import sys
import termios
-from portage import os, _unicode_decode, _unicode_encode
+from portage import os
from portage.output import get_term_size, set_term_size
-from portage.process import spawn_bash
from portage.util import writemsg
-def _can_test_pty_eof():
- """
- The _test_pty_eof() function seems to hang on most
- kernels other than Linux.
- This was reported for the following kernels which used to work fine
- without this EOF test: Darwin, AIX, FreeBSD. They seem to hang on
- the slave_file.close() call. Note that Python's implementation of
- openpty on Solaris already caused random hangs without this EOF test
- and hence is globally disabled.
- @rtype: bool
- @returns: True if _test_pty_eof() won't hang, False otherwise.
- """
- return platform.system() in ("Linux",)
-
-def _test_pty_eof():
- """
- Returns True if EOF appears to be handled correctly with pty
- devices. Raises an EnvironmentError from openpty() if it fails.
-
- This used to be used to detect if the following issue was fixed
- in the currently running version of python:
-
- http://bugs.python.org/issue5380
-
- However, array.fromfile() use has since been abandoned due to
- bugs that exist in all known versions of Python (including Python
- 2.7 and Python 3.2). See PipeReaderArrayTestCase, for example.
- This is somewhat unfortunate, since the combination of
- array.fromfile() and array.tofile() is approximately 10% faster
- than the combination of os.read() and os.write().
- """
-
- use_fork = False
-
- test_string = 2 * "blah blah blah\n"
- test_string = _unicode_decode(test_string,
- encoding='utf_8', errors='strict')
-
- # may raise EnvironmentError
- master_fd, slave_fd = pty.openpty()
-
- # Non-blocking mode is required for Darwin kernel.
- fcntl.fcntl(master_fd, fcntl.F_SETFL,
- fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
-
- # Disable post-processing of output since otherwise weird
- # things like \n -> \r\n transformations may occur.
- mode = termios.tcgetattr(slave_fd)
- mode[1] &= ~termios.OPOST
- termios.tcsetattr(slave_fd, termios.TCSANOW, mode)
-
- # Simulate a subprocess writing some data to the
- # slave end of the pipe, and then exiting.
- pid = None
- if use_fork:
- pids = spawn_bash(_unicode_encode("echo -n '%s'" % test_string,
- encoding='utf_8', errors='strict'), env=os.environ,
- fd_pipes={0:sys.stdin.fileno(), 1:slave_fd, 2:slave_fd},
- returnpid=True)
- if isinstance(pids, int):
- os.close(master_fd)
- os.close(slave_fd)
- raise EnvironmentError('spawn failed')
- pid = pids[0]
- else:
- os.write(slave_fd, _unicode_encode(test_string,
- encoding='utf_8', errors='strict'))
- os.close(slave_fd)
-
- # If using a fork, we must wait for the child here,
- # in order to avoid a race condition that would
- # lead to inconsistent results.
- if pid is not None:
- os.waitpid(pid, 0)
+# Disable the use of openpty on Solaris as it seems Python's openpty
+# implementation doesn't play nice on Solaris with Portage's
+# behaviour causing hangs/deadlocks.
+# Additional note for the future: on Interix, pipes do NOT work, so
+# _disable_openpty on Interix must *never* be True
+_disable_openpty = platform.system() in ("SunOS",)
- data = []
- iwtd = [master_fd]
- owtd = []
- ewtd = []
-
- while True:
-
- events = select.select(iwtd, owtd, ewtd)
- if not events[0]:
- # EOF
- break
-
- buf = None
- try:
- buf = os.read(master_fd, 1024)
- except OSError as e:
- # EIO happens with pty on Linux after the
- # slave end of the pty has been closed.
- if e.errno == errno.EIO:
- # EOF: return empty string of bytes
- buf = b''
- elif e.errno == errno.EAGAIN:
- # EAGAIN: return None
- buf = None
- else:
- raise
-
- if buf is None:
- pass
- elif not buf:
- # EOF
- break
- else:
- data.append(buf)
-
- os.close(master_fd)
-
- return test_string == _unicode_decode(b''.join(data), encoding='utf_8', errors='strict')
-
-# If _test_pty_eof() can't be used for runtime detection of
-# http://bugs.python.org/issue5380, openpty can't safely be used
-# unless we can guarantee that the current version of python has
-# been fixed (affects all current versions of python3). When
-# this issue is fixed in python3, we can add another sys.hexversion
-# conditional to enable openpty support in the fixed versions.
-if sys.hexversion >= 0x3000000 and not _can_test_pty_eof():
- _disable_openpty = True
-else:
- # Disable the use of openpty on Solaris as it seems Python's openpty
- # implementation doesn't play nice on Solaris with Portage's
- # behaviour causing hangs/deadlocks.
- # Additional note for the future: on Interix, pipes do NOT work, so
- # _disable_openpty on Interix must *never* be True
- _disable_openpty = platform.system() in ("SunOS",)
_tested_pty = False
-if not _can_test_pty_eof():
- # Skip _test_pty_eof() on systems where it hangs.
- _tested_pty = True
-
_fbsd_test_pty = platform.system() == 'FreeBSD'
def _create_pty_or_pipe(copy_term_size=None):
@@ -167,17 +36,7 @@ def _create_pty_or_pipe(copy_term_size=None):
got_pty = False
- global _disable_openpty, _fbsd_test_pty, _tested_pty
- if not (_tested_pty or _disable_openpty):
- try:
- if not _test_pty_eof():
- _disable_openpty = True
- except EnvironmentError as e:
- _disable_openpty = True
- writemsg("openpty failed: '%s'\n" % str(e),
- noiselevel=-1)
- del e
- _tested_pty = True
+ global _disable_openpty, _fbsd_test_pty
if _fbsd_test_pty and not _disable_openpty:
# Test for python openpty breakage after freebsd7 to freebsd8