aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/portage/util/_pty.py')
-rw-r--r--lib/portage/util/_pty.py27
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)