diff options
author | Jürg Billeter <j@bitron.ch> | 2017-07-21 07:56:25 +0200 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2017-07-25 17:14:34 +0000 |
commit | 1f35d21eda3ca302f1bf78d130609cf1597bcfc5 (patch) | |
tree | d1f7408484fa82416d4955e7ec77678223366622 | |
parent | 5e7cf0efb2cd5253635900fa150e68d8f5476ae1 (diff) | |
download | buildstream-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.py | 12 |
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): |