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