summaryrefslogtreecommitdiff
path: root/cmd2
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2019-11-19 01:19:45 -0500
committerGitHub <noreply@github.com>2019-11-19 01:19:45 -0500
commit8c00d342ee3967e09cce436d76208238307d1cd4 (patch)
treeba7a6658f7f0520aeab180b5809a01d00bdc5429 /cmd2
parent73535e1ff82b49c594fc694ef0ea898d46742750 (diff)
parent1a77e7ba6bc1bd84b70589f966c726f616ce6a96 (diff)
downloadcmd2-git-8c00d342ee3967e09cce436d76208238307d1cd4.tar.gz
Merge pull request #811 from python-cmd2/win_fix
Fixed bug where pipe processes were not being stopped by Ctrl-C on Windows
Diffstat (limited to 'cmd2')
-rw-r--r--cmd2/cmd2.py24
-rw-r--r--cmd2/utils.py6
2 files changed, 15 insertions, 15 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 051e6f7c..29bf9529 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -56,9 +56,9 @@ from .rl_utils import rl_type, RlType, rl_get_point, rl_set_prompt, vt100_suppor
# Set up readline
if rl_type == RlType.NONE: # pragma: no cover
- rl_warning = "Readline features including tab completion have been disabled since no \n" \
- "supported version of readline was found. To resolve this, install \n" \
- "pyreadline on Windows or gnureadline on Mac.\n\n"
+ rl_warning = ("Readline features including tab completion have been disabled since no\n"
+ "supported version of readline was found. To resolve this, install pyreadline\n"
+ "on Windows or gnureadline on Mac.\n\n")
sys.stderr.write(ansi.style_warning(rl_warning))
else:
from .rl_utils import rl_force_redisplay, readline
@@ -1824,24 +1824,22 @@ class Cmd(cmd.Cmd):
subproc_stdin = io.open(read_fd, 'r')
new_stdout = io.open(write_fd, 'w')
- # Set options to not forward signals to the pipe process. If a Ctrl-C event occurs,
- # our sigint handler will forward it only to the most recent pipe process. This makes
- # sure pipe processes close in the right order (most recent first).
+ # Create pipe process in a separate group to isolate our signals from it. If a Ctrl-C event occurs,
+ # our sigint handler will forward it only to the most recent pipe process. This makes sure pipe
+ # processes close in the right order (most recent first).
+ kwargs = dict()
if sys.platform == 'win32':
- creationflags = subprocess.CREATE_NEW_PROCESS_GROUP
- start_new_session = False
+ kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
else:
- creationflags = 0
- start_new_session = True
+ kwargs['start_new_session'] = True
# For any stream that is a StdSim, we will use a pipe so we can capture its output
proc = subprocess.Popen(statement.pipe_to,
stdin=subproc_stdin,
stdout=subprocess.PIPE if isinstance(self.stdout, utils.StdSim) else self.stdout,
stderr=subprocess.PIPE if isinstance(sys.stderr, utils.StdSim) else sys.stderr,
- creationflags=creationflags,
- start_new_session=start_new_session,
- shell=True)
+ shell=True,
+ **kwargs)
# Popen was called with shell=True so the user can chain pipe commands and redirect their output
# like: !ls -l | grep user | wc -l > out.txt. But this makes it difficult to know if the pipe process
diff --git a/cmd2/utils.py b/cmd2/utils.py
index 3155c64a..a1a0d377 100644
--- a/cmd2/utils.py
+++ b/cmd2/utils.py
@@ -517,10 +517,12 @@ class ProcReader(object):
self._err_thread.start()
def send_sigint(self) -> None:
- """Send a SIGINT to the process similar to if <Ctrl>+C were pressed."""
+ """Send a SIGINT to the process similar to if <Ctrl>+C were pressed"""
import signal
if sys.platform.startswith('win'):
- self._proc.send_signal(signal.CTRL_C_EVENT)
+ # cmd2 started the Windows process in a new process group. Therefore
+ # a CTRL_C_EVENT can't be sent to it. Send a CTRL_BREAK_EVENT instead.
+ self._proc.send_signal(signal.CTRL_BREAK_EVENT)
else:
# Since cmd2 uses shell=True in its Popen calls, we need to send the SIGINT to
# the whole process group to make sure it propagates further than the shell