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
# 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):
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
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
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")
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
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)