Skip to content

Commit 6df4b98

Browse files
authored
Merge pull request #587 from python-cmd2/signal_threads
Ruggedized registration of SIGINT signal handler
2 parents 7b2603e + 8ae418d commit 6df4b98

File tree

3 files changed

+15
-6
lines changed

3 files changed

+15
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
## 0.9.7 (TBD, 2018)
2+
* Enhancements
3+
* **cmdloop** now only attempts to register a custom signal handler for SIGINT if running in the main thread
24
* Deletions (potentially breaking changes)
35
* Deleted ``Cmd.colorize()`` and ``Cmd._colorcodes`` which were deprecated in 0.9.5
46

cmd2/cmd2.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3588,10 +3588,12 @@ def cmdloop(self, intro: Optional[str]=None) -> None:
35883588
if callargs:
35893589
self.cmdqueue.extend(callargs)
35903590

3591-
# Register a SIGINT signal handler for Ctrl+C
3592-
import signal
3593-
original_sigint_handler = signal.getsignal(signal.SIGINT)
3594-
signal.signal(signal.SIGINT, self.sigint_handler)
3591+
# Only the main thread is allowed to set a new signal handler in Python, so only attempt if that is the case
3592+
if threading.current_thread() is threading.main_thread():
3593+
# Register a SIGINT signal handler for Ctrl+C
3594+
import signal
3595+
original_sigint_handler = signal.getsignal(signal.SIGINT)
3596+
signal.signal(signal.SIGINT, self.sigint_handler)
35953597

35963598
# Grab terminal lock before the prompt has been drawn by readline
35973599
self.terminal_lock.acquire()
@@ -3625,8 +3627,9 @@ def cmdloop(self, intro: Optional[str]=None) -> None:
36253627
# This will also zero the lock count in case cmdloop() is called again
36263628
self.terminal_lock.release()
36273629

3628-
# Restore the original signal handler
3629-
signal.signal(signal.SIGINT, original_sigint_handler)
3630+
if threading.current_thread() is threading.main_thread():
3631+
# Restore the original signal handler
3632+
signal.signal(signal.SIGINT, original_sigint_handler)
36303633

36313634
if self.exit_code is not None:
36323635
sys.exit(self.exit_code)

docs/settingchanges.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ set to ``False``, then the current line will simply be cancelled.
140140
(Cmd) typing a comma^C
141141
(Cmd)
142142

143+
.. warning::
144+
The default SIGINT behavior will only function properly if **cmdloop** is running
145+
in the main thread.
146+
143147

144148
Timing
145149
======

0 commit comments

Comments
 (0)