diff options
author | Brian Curtin <brian.curtin@gmail.com> | 2010-04-02 23:26:06 (GMT) |
---|---|---|
committer | Brian Curtin <brian.curtin@gmail.com> | 2010-04-02 23:26:06 (GMT) |
commit | e5aa886b4449c9b2db93591c58511ea3620c9b67 (patch) | |
tree | aa333dc52ff6f99c1443b117b26c50a6afbdb7a9 /Modules/posixmodule.c | |
parent | a04c7a0f169caf09b181df05836e4cf175f37dbe (diff) | |
download | cpython-e5aa886b4449c9b2db93591c58511ea3620c9b67.zip cpython-e5aa886b4449c9b2db93591c58511ea3620c9b67.tar.gz cpython-e5aa886b4449c9b2db93591c58511ea3620c9b67.tar.bz2 |
Implement #1220212. Add os.kill support for Windows.
os.kill takes one of two newly added signals, CTRL_C_EVENT and
CTRL_BREAK_EVENT, or any integer value. The events are a special case
which work with subprocess console applications which implement a
special console control handler. Any other value but those two will
cause os.kill to use TerminateProcess, outright killing the process.
This change adds win_console_handler.py, which is a script to implement
SetConsoleCtrlHandler and applicable handler function, using ctypes.
subprocess also gets another attribute which is a necessary flag to
creationflags in Popen in order to send the CTRL events.
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8fb7aaa..53eb237 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4075,6 +4075,53 @@ posix_killpg(PyObject *self, PyObject *args) } #endif +#ifdef MS_WINDOWS +PyDoc_STRVAR(win32_kill__doc__, +"kill(pid, sig)\n\n\ +Kill a process with a signal."); + +static PyObject * +win32_kill(PyObject *self, PyObject *args) +{ + PyObject *result, handle_obj; + DWORD pid, sig, err; + HANDLE handle; + + if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig)) + return NULL; + + /* Console processes which share a common console can be sent CTRL+C or + CTRL+BREAK events, provided they handle said events. */ + if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { + if (GenerateConsoleCtrlEvent(sig, pid) == 0) { + err = GetLastError(); + PyErr_SetFromWindowsErr(err); + } + else + Py_RETURN_NONE; + } + + /* If the signal is outside of what GenerateConsoleCtrlEvent can use, + attempt to open and terminate the process. */ + handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + if (handle == NULL) { + err = GetLastError(); + return PyErr_SetFromWindowsErr(err); + } + + if (TerminateProcess(handle, sig) == 0) { + err = GetLastError(); + result = PyErr_SetFromWindowsErr(err); + } else { + Py_INCREF(Py_None); + result = Py_None; + } + + CloseHandle(handle); + return result; +} +#endif /* MS_WINDOWS */ + #ifdef HAVE_PLOCK #ifdef HAVE_SYS_LOCK_H @@ -8660,6 +8707,7 @@ static PyMethodDef posix_methods[] = { {"popen3", win32_popen3, METH_VARARGS}, {"popen4", win32_popen4, METH_VARARGS}, {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, + {"kill", win32_kill, METH_VARARGS, win32_kill__doc__}, #else #if defined(PYOS_OS2) && defined(PYCC_GCC) {"popen2", os2emx_popen2, METH_VARARGS}, |