eryksun added the comment:
> Which python level signal handler will CTRL_BREAK_EVENT
> trigger?
The CRT maps it to a non-standard signal, SIGBREAK (21). It's defined in the
signal module.
> GenerateConsoleCtrlEvent has different limitations for
> CTRL_BREAK_EVENT and CTRL_C_EVENT according to MSDN;
> I was referring to the CTRL_C_EVENT limitations.
When creating a process group, the ConsoleFlags value in the process parameters
is set to ignore CTRL_C_EVENT. You'll still get a DBG_CONTROL_C exception if a
debugger is attached, but otherwise kernel32!CtrlRoutine ignores Ctrl+C. As you
say, the docs state that "[CTRL_C_EVENT] cannot be generated for process
groups". But it *does* work if you remove the ignore flag. This flag gets
set/unset by assigning/removing a NULL handler.
Here's a revised example to enable Ctrl+C in the child, disable Python's INT
handler, and then generate CTRL_C_EVENT to kill the child and verify that the
exit code is STATUS_CONTROL_C_EXIT.
import os
import sys
import signal
import subprocess
import threading
STATUS_CONTROL_C_EXIT = 0xC000013A
p = subprocess.Popen([sys.executable, '-i', '-c',
'import ctypes, signal;'
'kernel32 = ctypes.windll.kernel32;'
'kernel32.SetConsoleCtrlHandler(None, 0);'
'signal.signal(signal.SIGINT, signal.SIG_DFL)'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
p.stderr.read(1) # poor man's WaitForInputIdle
os.kill(p.pid, signal.CTRL_C_EVENT)
watchdog = threading.Timer(5, p.terminate)
watchdog.start()
exitcode = p.wait()
watchdog.cancel()
if exitcode < 0:
exitcode += 2 ** 32
assert exitcode == STATUS_CONTROL_C_EXIT
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue23948>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com