diff --git a/NEWS b/NEWS index ac0e36b7..3f64c8d2 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ using an environment variable. * #1013: Send database passwords to MongoDB via anonymous pipe, which is more secure than using "--password" on the command-line. + * #1015: When ctrl-C is pressed, ensure Borg actually exits. * Add a "verify_tls" option to the Uptime Kuma monitoring hook for disabling TLS verification. 1.9.12 diff --git a/borgmatic/signals.py b/borgmatic/signals.py index 7ec31d91..40fa5295 100644 --- a/borgmatic/signals.py +++ b/borgmatic/signals.py @@ -24,6 +24,9 @@ def handle_signal(signal_number, frame): logger.critical('Exiting due to TERM signal') sys.exit(EXIT_CODE_FROM_SIGNAL + signal.SIGTERM) elif signal_number == signal.SIGINT: + # Borg doesn't always exit on a SIGINT, so give it a little encouragement. + os.killpg(os.getpgrp(), signal.SIGTERM) + raise KeyboardInterrupt() diff --git a/tests/unit/test_signals.py b/tests/unit/test_signals.py index 86bb759c..57ee14ab 100644 --- a/tests/unit/test_signals.py +++ b/tests/unit/test_signals.py @@ -26,7 +26,7 @@ def test_handle_signal_bails_on_recursion(): def test_handle_signal_exits_on_sigterm(): signal_number = module.signal.SIGTERM frame = flexmock(f_back=flexmock(f_code=flexmock(co_name='something'))) - flexmock(module.os).should_receive('getpgrp').and_return(flexmock) + flexmock(module.os).should_receive('getpgrp').and_return(flexmock()) flexmock(module.os).should_receive('killpg') flexmock(module.sys).should_receive('exit').with_args( module.EXIT_CODE_FROM_SIGNAL + signal_number @@ -38,8 +38,10 @@ def test_handle_signal_exits_on_sigterm(): def test_handle_signal_raises_on_sigint(): signal_number = module.signal.SIGINT frame = flexmock(f_back=flexmock(f_code=flexmock(co_name='something'))) - flexmock(module.os).should_receive('getpgrp').and_return(flexmock) - flexmock(module.os).should_receive('killpg') + process_group = flexmock() + flexmock(module.os).should_receive('getpgrp').and_return(process_group) + flexmock(module.os).should_receive('killpg').with_args(process_group, module.signal.SIGINT) + flexmock(module.os).should_receive('killpg').with_args(process_group, module.signal.SIGTERM) flexmock(module.sys).should_receive('exit').never() with pytest.raises(KeyboardInterrupt):