From 8ae418d33320135a4eea3c864065aa6868497eeb Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Sun, 21 Oct 2018 17:21:56 -0400 Subject: cmdloop now checks to see if it is running in the main thread before attempting to register a signal handler for SIGINT --- CHANGELOG.md | 2 ++ cmd2/cmd2.py | 15 +++++++++------ docs/settingchanges.rst | 4 ++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d31f82d..9f2a23db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ ## 0.9.7 (TBD, 2018) +* Enhancements + * **cmdloop** now only attempts to register a custom signal handler for SIGINT if running in the main thread * Deletions (potentially breaking changes) * Deleted ``Cmd.colorize()`` and ``Cmd._colorcodes`` which were deprecated in 0.9.5 diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index e08db8c5..b9e6aa99 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -3588,10 +3588,12 @@ a..b, a:b, a:, ..b items by indices (inclusive) if callargs: self.cmdqueue.extend(callargs) - # Register a SIGINT signal handler for Ctrl+C - import signal - original_sigint_handler = signal.getsignal(signal.SIGINT) - signal.signal(signal.SIGINT, self.sigint_handler) + # Only the main thread is allowed to set a new signal handler in Python, so only attempt if that is the case + if threading.current_thread() is threading.main_thread(): + # Register a SIGINT signal handler for Ctrl+C + import signal + original_sigint_handler = signal.getsignal(signal.SIGINT) + signal.signal(signal.SIGINT, self.sigint_handler) # Grab terminal lock before the prompt has been drawn by readline self.terminal_lock.acquire() @@ -3625,8 +3627,9 @@ a..b, a:b, a:, ..b items by indices (inclusive) # This will also zero the lock count in case cmdloop() is called again self.terminal_lock.release() - # Restore the original signal handler - signal.signal(signal.SIGINT, original_sigint_handler) + if threading.current_thread() is threading.main_thread(): + # Restore the original signal handler + signal.signal(signal.SIGINT, original_sigint_handler) if self.exit_code is not None: sys.exit(self.exit_code) diff --git a/docs/settingchanges.rst b/docs/settingchanges.rst index 25a671ab..1399c9fe 100644 --- a/docs/settingchanges.rst +++ b/docs/settingchanges.rst @@ -140,6 +140,10 @@ set to ``False``, then the current line will simply be cancelled. (Cmd) typing a comma^C (Cmd) +.. warning:: + The default SIGINT behavior will only function properly if **cmdloop** is running + in the main thread. + Timing ====== -- cgit v1.2.1