diff options
Diffstat (limited to 'lib/portage/util/_pty.py')
-rw-r--r-- | lib/portage/util/_pty.py | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/lib/portage/util/_pty.py b/lib/portage/util/_pty.py index e58f95e0a..9d090b711 100644 --- a/lib/portage/util/_pty.py +++ b/lib/portage/util/_pty.py @@ -1,9 +1,11 @@ -# Copyright 2010-2011 Gentoo Foundation +# Copyright 2010-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 +import asyncio import platform import pty import termios +from typing import Optional, Union from portage import os from portage.output import get_term_size, set_term_size @@ -19,17 +21,21 @@ _disable_openpty = platform.system() in ("SunOS",) _fbsd_test_pty = platform.system() == "FreeBSD" -def _create_pty_or_pipe(copy_term_size=None): +def _create_pty_or_pipe( + copy_term_size: Optional[int] = None, +) -> tuple[Union[asyncio.Future, bool], int, int]: """ Try to create a pty and if then fails then create a normal - pipe instead. + pipe instead. If a Future is returned for pty_ready, then the + caller should wait for it (which comes from set_term_size + because it spawns stty). @param copy_term_size: If a tty file descriptor is given then the term size will be copied to the pty. @type copy_term_size: int @rtype: tuple - @return: A tuple of (is_pty, master_fd, slave_fd) where - is_pty is True if a pty was successfully allocated, and + @return: A tuple of (pty_ready, master_fd, slave_fd) where + pty_ready is asyncio.Future or True if a pty was successfully allocated, and False if a normal pipe was allocated. """ @@ -56,9 +62,9 @@ def _create_pty_or_pipe(copy_term_size=None): try: master_fd, slave_fd = pty.openpty() got_pty = True - except EnvironmentError as e: + except OSError as e: _disable_openpty = True - writemsg("openpty failed: '%s'\n" % str(e), noiselevel=-1) + writemsg(f"openpty failed: '{str(e)}'\n", noiselevel=-1) del e master_fd, slave_fd = os.pipe() @@ -69,8 +75,11 @@ def _create_pty_or_pipe(copy_term_size=None): mode[1] &= ~termios.OPOST termios.tcsetattr(slave_fd, termios.TCSANOW, mode) + pty_ready = None if got_pty and copy_term_size is not None and os.isatty(copy_term_size): rows, columns = get_term_size() - set_term_size(rows, columns, slave_fd) + pty_ready = set_term_size(rows, columns, slave_fd) - return (got_pty, master_fd, slave_fd) + # The future only exists when got_pty is True, so we can + # return the future in lieu of got_pty when it exists. + return (got_pty if pty_ready is None else pty_ready, master_fd, slave_fd) |