Split out a portage._create_pty_or_pipe() function to avoid duplicate code.
authorZac Medico <zmedico@gentoo.org>
Sat, 12 Jul 2008 08:43:29 +0000 (08:43 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 12 Jul 2008 08:43:29 +0000 (08:43 -0000)
svn path=/main/trunk/; revision=11024

pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/tests/process/test_poll.py

index b111157eacc95cd2b5f809131d183db2d783ddcb..a282278c960eda15c1c3050a002a8ffa25b35000 100644 (file)
@@ -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
index 535ea9ed753cc4c2eab45c166bc044e111a3c6ff..4031f64ccf675a11744fbaf55e192cadb85e6296 100644 (file)
@@ -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
index e8de967f7e7a0db0f9161ccf8371a5cce4222f3f..8a52f45777084a3d55f805f6fd50190ad135d3a9 100644 (file)
@@ -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)