summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2017-07-21 07:56:25 +0200
committerJürg Billeter <j@bitron.ch>2017-07-25 18:38:39 +0100
commit8f401127c450ea1c2a1e2878d2ac28a7166d355c (patch)
tree7269de9b0c79403e5e923e7a48477da9179fbb0d
parente45b36750cd695cc1566a27b8f2f37a18c2ef159 (diff)
downloadbuildstream-8f401127c450ea1c2a1e2878d2ac28a7166d355c.tar.gz
_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
-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):