tools/qvm-run: handle Ctrl+C nicely

Do not exit with ugly python backtrace, simply interrupt the command
(propagate SIGINT) and exit.

QubesOS/qubes-issues#4532
This commit is contained in:
Marek Marczykowski-Górecki 2018-12-07 04:22:05 +01:00
parent 9acce13a35
commit 32cbc59ba9
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724

View File

@ -19,7 +19,9 @@
# with this program; if not, see <http://www.gnu.org/licenses/>.
''' qvm-run tool'''
import contextlib
import os
import signal
import subprocess
import sys
@ -114,6 +116,7 @@ def copy_stdin(stream):
# multiprocessing.Process have sys.stdin connected to /dev/null, use fd 0
# directly
while True:
try:
# select so this code works even if fd 0 is non-blocking
select.select([0], [], [])
data = os.read(0, 65536)
@ -121,6 +124,8 @@ def copy_stdin(stream):
break
stream.write(data)
stream.flush()
except KeyboardInterrupt:
break
stream.close()
def main(args=None, app=None):
@ -205,7 +210,12 @@ def main(args=None, app=None):
if args.gui and not args.dispvm:
wait_session = vm.run_service('qubes.WaitForSession',
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
try:
wait_session.communicate(vm.default_user.encode())
except KeyboardInterrupt:
with contextlib.suppress(ProcessLookupError):
wait_session.send_signal(signal.SIGINT)
break
if args.service:
service = args.cmd
else:
@ -239,6 +249,13 @@ def main(args=None, app=None):
sys.stdout.flush()
vm.log.error(str(e))
return -1
try:
for proc in procs:
retcode = max(retcode, proc.wait())
except KeyboardInterrupt:
for proc in procs:
with contextlib.suppress(ProcessLookupError):
proc.send_signal(signal.SIGINT)
for proc in procs:
retcode = max(retcode, proc.wait())
finally: