Skip to content

Commit 097bbbf

Browse files
committed
Properly handle SIGINT and SIGTERM on spawed subprocesses
Fixes #7 Signed-off-by: Pedro Algarvio <[email protected]>
1 parent 5627668 commit 097bbbf

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

changelog/7.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Properly handle `SIGINT` and `SIGTERM` on spawed subprocesses

src/ptscripts/process.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import asyncio.subprocess
66
import logging
77
import os
8+
import signal
89
import subprocess
910
import sys
1011
from datetime import datetime
@@ -139,6 +140,12 @@ async def _subprocess_run(
139140
):
140141
stdout = subprocess.PIPE
141142
stderr = subprocess.PIPE
143+
kwargs = {}
144+
# Run in a separate program group
145+
if sys.platform.startswith("win"):
146+
kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP
147+
else:
148+
kwargs["preexec_fn"] = os.setpgrp
142149
proc = await _create_subprocess_exec(
143150
*cmdline,
144151
stdout=stdout,
@@ -147,8 +154,13 @@ async def _subprocess_run(
147154
limit=1,
148155
no_output_timeout_secs=no_output_timeout_secs,
149156
capture=capture,
157+
**kwargs,
150158
)
151-
stdout, stderr = await proc.communicate()
159+
loop = asyncio.get_running_loop()
160+
for signame in ("SIGINT", "SIGTERM"):
161+
sig = getattr(signal, signame)
162+
loop.add_signal_handler(sig, proc.terminate)
163+
stdout, stderr = await asyncio.shield(proc.communicate())
152164
result = subprocess.CompletedProcess(
153165
args=cmdline,
154166
stdout=stdout,

0 commit comments

Comments
 (0)