From 5f6d6bef1dec5667e6f7ec5eb3f0b3dfbfc93c83 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 12 Jul 2008 08:43:29 +0000 Subject: Split out a portage._create_pty_or_pipe() function to avoid duplicate code. svn path=/main/trunk/; revision=11024 --- pym/_emerge/__init__.py | 27 +---------- pym/portage/__init__.py | 86 ++++++++++++++++++++++------------ pym/portage/tests/process/test_poll.py | 29 ++---------- 3 files changed, 62 insertions(+), 80 deletions(-) (limited to 'pym') diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index b111157ea..a282278c9 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -2533,35 +2533,12 @@ class EbuildPhase(SubProcess): settings.get("EBUILD_EXIT_STATUS_FILE")) if logfile: - if portage._disable_openpty: - master_fd, slave_fd = os.pipe() - else: - from pty import openpty - try: - master_fd, slave_fd = openpty() - got_pty = True - except EnvironmentError, e: - portage._disable_openpty = True - portage.writemsg("openpty failed: '%s'\n" % str(e), - noiselevel=-1) - del e - master_fd, slave_fd = os.pipe() - - if got_pty: - # Disable post-processing of output since otherwise weird - # things like \n -> \r\n transformations may occur. - import termios - mode = termios.tcgetattr(slave_fd) - mode[1] &= ~termios.OPOST - termios.tcsetattr(slave_fd, termios.TCSANOW, mode) + got_pty, master_fd, slave_fd = \ + portage._create_pty_or_pipe(copy_term_size=fd_pipes_orig[1]) fcntl.fcntl(master_fd, fcntl.F_SETFL, fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK) - if got_pty and os.isatty(fd_pipes_orig[1]): - from portage.output import get_term_size, set_term_size - rows, columns = get_term_size() - set_term_size(rows, columns, slave_fd) fd_pipes[0] = fd_pipes_orig[0] fd_pipes[1] = slave_fd fd_pipes[2] = slave_fd diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 535ea9ed7..4031f64cc 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -2902,6 +2902,54 @@ def _shell_quote(s): # stop trying to use it after the first failure. _disable_openpty = False +def _create_pty_or_pipe(copy_term_size=None): + """ + Try to create a pty and if then fails then create a normal + pipe instead. + + @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 + @returns: A tuple of (is_pty, master_fd, slave_fd) where + is_pty is True if a pty was successfully allocated, and + False if a normal pipe was allocated. + """ + + got_pty = False + + global _disable_openpty + if _disable_openpty: + master_fd, slave_fd = os.pipe() + else: + from pty import openpty + try: + master_fd, slave_fd = openpty() + got_pty = True + except EnvironmentError, e: + _disable_openpty = True + writemsg("openpty failed: '%s'\n" % str(e), + noiselevel=-1) + del e + master_fd, slave_fd = os.pipe() + + if got_pty: + # Disable post-processing of output since otherwise weird + # things like \n -> \r\n transformations may occur. + import termios + mode = termios.tcgetattr(slave_fd) + mode[1] &= ~termios.OPOST + termios.tcsetattr(slave_fd, termios.TCSANOW, mode) + + if got_pty and \ + copy_term_size is not None and \ + os.isatty(copy_term_size): + from portage.output import get_term_size, set_term_size + rows, columns = get_term_size() + set_term_size(rows, columns, slave_fd) + + return (got_pty, master_fd, slave_fd) + # XXX This would be to replace getstatusoutput completely. # XXX Issue: cannot block execution. Deadlock condition. def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, **keywords): @@ -2984,26 +3032,12 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero del keywords["logfile"] if 1 not in fd_pipes or 2 not in fd_pipes: raise ValueError(fd_pipes) - global _disable_openpty - if _disable_openpty: - master_fd, slave_fd = os.pipe() - else: - from pty import openpty - try: - master_fd, slave_fd = openpty() - got_pty = True - except EnvironmentError, e: - _disable_openpty = True - writemsg("openpty failed: '%s'\n" % str(e), noiselevel=1) - del e - master_fd, slave_fd = os.pipe() - if got_pty: - # Disable post-processing of output since otherwise weird - # things like \n -> \r\n transformations may occur. - import termios - mode = termios.tcgetattr(slave_fd) - mode[1] &= ~termios.OPOST - termios.tcsetattr(slave_fd, termios.TCSANOW, mode) + + fd_pipes.setdefault(0, sys.stdin.fileno()) + fd_pipes_orig = fd_pipes.copy() + + got_pty, master_fd, slave_fd = \ + _create_pty_or_pipe(copy_term_size=fd_pipes_orig[1]) # We must set non-blocking mode before we close the slave_fd # since otherwise the fcntl call can fail on FreeBSD (the child @@ -3014,12 +3048,6 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero fcntl.fcntl(master_fd, fcntl.F_SETFL, fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK) - fd_pipes.setdefault(0, sys.stdin.fileno()) - fd_pipes_orig = fd_pipes.copy() - if got_pty and os.isatty(fd_pipes_orig[1]): - from portage.output import get_term_size, set_term_size - rows, columns = get_term_size() - set_term_size(rows, columns, slave_fd) fd_pipes[0] = fd_pipes_orig[0] fd_pipes[1] = slave_fd fd_pipes[2] = slave_fd @@ -4755,7 +4783,8 @@ def prepare_build_dirs(myroot, mysettings, cleanup): writemsg("!!! Disabling logging.\n", noiselevel=-1) while "PORT_LOGDIR" in mysettings: del mysettings["PORT_LOGDIR"] - if "PORT_LOGDIR" in mysettings: + if "PORT_LOGDIR" in mysettings and \ + os.access(mysettings["PORT_LOGDIR"], os.W_OK): logid_path = os.path.join(mysettings["PORTAGE_BUILDDIR"], ".logid") if not os.path.exists(logid_path): f = open(logid_path, "w") @@ -5155,8 +5184,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, have_build_dirs = True # PORTAGE_LOG_FILE is set above by the prepare_build_dirs() call. logfile = mysettings.get("PORTAGE_LOG_FILE") - if logfile and not os.access(os.path.dirname(logfile), os.W_OK): - logfile = None + if have_build_dirs: env_file = os.path.join(mysettings["T"], "environment") env_stat = None diff --git a/pym/portage/tests/process/test_poll.py b/pym/portage/tests/process/test_poll.py index e8de967f7..8a52f4577 100644 --- a/pym/portage/tests/process/test_poll.py +++ b/pym/portage/tests/process/test_poll.py @@ -62,31 +62,8 @@ class PtyReaderTestCase(PipeReaderTestCase): self.assertEqual(test_string, consumer_value) def _create_pipe(self): - got_pty = False - - if portage._disable_openpty: - master_fd, slave_fd = os.pipe() - else: - from pty import openpty - try: - master_fd, slave_fd = openpty() - got_pty = True - except EnvironmentError, e: - portage._disable_openpty = True - portage.writemsg("openpty failed: '%s'\n" % str(e), - noiselevel=-1) - del e - master_fd, slave_fd = os.pipe() - - if got_pty: - # 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) - - if got_pty and sys.stdout.isatty(): - rows, columns = get_term_size() - set_term_size(rows, columns, slave_fd) + + got_pty, master_fd, slave_fd = \ + portage._create_pty_or_pipe(copy_term_size=sys.stdout.fileno()) return (master_fd, slave_fd) -- cgit v1.2.3-1-g7c22