summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2017-07-21 07:56:25 +0200
committerTristan Van Berkom <tristan.van.berkom@gmail.com>2017-07-25 17:14:34 +0000
commit1f35d21eda3ca302f1bf78d130609cf1597bcfc5 (patch)
treed1f7408484fa82416d4955e7ec77678223366622
parent5e7cf0efb2cd5253635900fa150e68d8f5476ae1 (diff)
downloadbuildstream-interactive-terminal.tar.gz
_sandboxbwrap.py: Restore terminal after exit of interactive childinteractive-terminal
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
-rw-r--r--buildstream/_sandboxbwrap.py12
1 files changed, 12 insertions, 0 deletions
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):