Index: test/lit.cfg =================================================================== --- test/lit.cfg +++ test/lit.cfg @@ -13,6 +13,7 @@ import sys import tempfile import time +import pty import lit.Test import lit.formats @@ -35,8 +36,54 @@ self.cpp_flags = list(cpp_flags) self.ld_flags = list(ld_flags) self.exec_env = dict(exec_env) - - def execute_command(self, command, in_dir=None): + if sys.stdout.isatty(): + self._execute_command_helper = LibcxxTestFormat._execute_command_pty + else: + self._execute_command_helper = LibcxxTestFormat._execute_command_normal + + @staticmethod + def _close_raw_fd(fd): + try: + os.close(fd) + except: + pass + + @staticmethod + def _read_and_close_pty(p): + os.close(p[1]) + with os.fdopen(p[0], 'r') as f: + out = '' + try: + out = f.read() + except IOError: + pass + return out + + @staticmethod + def _execute_command_pty(command, in_dir=None): + try: + out_pty = tuple(pty.openpty()) + err_pty = tuple(pty.openpty()) + kwargs = { + 'stdin' :subprocess.PIPE, + 'stdout':out_pty[1], + 'stderr':err_pty[1], + 'close_fds':True, + } + if in_dir: + kwargs['cwd'] = in_dir + p = subprocess.Popen(command, **kwargs) + exitCode = p.wait() + out = LibcxxTestFormat._read_and_close_pty(out_pty) + err = LibcxxTestFormat._read_and_close_pty(err_pty) + except: + for fd in out_pty + err_pty: + LibcxxTestFormat._close_raw_fd(fd) + raise + return out,err,exitCode + + @staticmethod + def _execute_command_normal(command, in_dir=None): kwargs = { 'stdin' :subprocess.PIPE, 'stdout':subprocess.PIPE, @@ -47,11 +94,13 @@ p = subprocess.Popen(command, **kwargs) out,err = p.communicate() exitCode = p.wait() + return out,err,exitCode + def execute_command(self, command, in_dir=None): + out,err,exitCode = self._execute_command_helper(command, in_dir) # Detect Ctrl-C in subprocess. if exitCode == -signal.SIGINT: raise KeyboardInterrupt - return out, err, exitCode def execute(self, test, lit_config):