From 1f35d21eda3ca302f1bf78d130609cf1597bcfc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Billeter?= Date: Fri, 21 Jul 2017 07:56:25 +0200 Subject: _sandboxbwrap.py: Restore terminal after exit of interactive child Make the main BuildStream process the foreground process again when the interactive child exits. Otherwise the next read() on stdin will trigger SIGTTIN and stop the process. This is required because the sandboxed process does not have permission to do this on its own (running in separate PID namespace). dash still prints an error because it fails to restore the foreground process, however, this is harmless. bash doesn't print an error in this case, but the behavior is otherwise identical. Fixes #41 --- buildstream/_sandboxbwrap.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/buildstream/_sandboxbwrap.py b/buildstream/_sandboxbwrap.py index ceec6108a..12f3e3b09 100644 --- a/buildstream/_sandboxbwrap.py +++ b/buildstream/_sandboxbwrap.py @@ -382,6 +382,18 @@ class SandboxBwrap(Sandbox): process.communicate() exit_code = process.poll() + if interactive: + # Make this process the foreground process again, otherwise the + # next read() on stdin will trigger SIGTTIN and stop the process. + # This is required because the sandboxed process does not have + # permission to do this on its own (running in separate PID namespace). + # + # tcsetpgrp() will trigger SIGTTOU when called from a background + # process, so ignore it temporarily. + handler = signal.signal(signal.SIGTTOU, signal.SIG_IGN) + os.tcsetpgrp(0, os.getpid()) + signal.signal(signal.SIGTTOU, handler) + return exit_code def try_remove_device(self, device_path): -- cgit v1.2.1