diff --git a/src/execo_engine/utils.py b/src/execo_engine/utils.py index 8d055872887f38f1ee82302e7fe0d41b3cf95014..0082fe9c6325808bd64fdf27f17144a23d016fbe 100644 --- a/src/execo_engine/utils.py +++ b/src/execo_engine/utils.py @@ -17,7 +17,7 @@ # along with Execo. If not, see <http://www.gnu.org/licenses/> from execo.utils import MAXFD -import os, unicodedata, re, sys, ctypes, signal +import os, unicodedata, re, sys, ctypes, signal, pty def _redirect_fd(fileno, filename): # create and open file filename, and redirect open file fileno to it @@ -45,9 +45,12 @@ def _disable_sigs(sigs): SIG_BLOCK = 0 libc.sigprocmask(SIG_BLOCK, ctypes.pointer(mask), 0) -def _tee_fd(fileno, filename): +def _tee_fd(fileno, filename, use_pty): # create and open file filename, and duplicate open file fileno to it - pr, pw = os.pipe() + if use_pty: + pr, pw = pty.openpty() + else: + pr, pw = os.pipe() pid = os.fork() if pid == 0: os.dup2(pr, 0) @@ -78,12 +81,12 @@ def redirect_outputs(stdout_filename, stderr_filename): # and 0 as the buffer size (unbuffered) sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1 if sys.version_info >= (3,) else 0) -def copy_outputs(stdout_filename, stderr_filename): +def copy_outputs(stdout_filename, stderr_filename, use_pty=False): """Copy, and optionnaly merge, stdout and stderr to file(s)""" sys.stdout.flush() sys.stderr.flush() - _tee_fd(1, stdout_filename) - _tee_fd(2, stderr_filename) + _tee_fd(1, stdout_filename, use_pty) + _tee_fd(2, stderr_filename, use_pty) # additionnaly force stdout unbuffered by reopening stdout # file descriptor with write mode # and 0 as the buffer size (unbuffered)