Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
eb24d749
Commit
eb24d749
authored
Apr 12, 2010
by
Brian Curtin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Port #1220212 (os.kill for Win32) to py3k.
parent
b2416e54
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
200 additions
and
6 deletions
+200
-6
Doc/library/os.rst
Doc/library/os.rst
+8
-1
Doc/library/signal.rst
Doc/library/signal.rst
+14
-0
Doc/library/subprocess.rst
Doc/library/subprocess.rst
+3
-2
Lib/subprocess.py
Lib/subprocess.py
+4
-0
Lib/test/test_os.py
Lib/test/test_os.py
+63
-3
Lib/test/win_console_handler.py
Lib/test/win_console_handler.py
+43
-0
Lib/unittest/test/test_break.py
Lib/unittest/test/test_break.py
+2
-0
Modules/posixmodule.c
Modules/posixmodule.c
+48
-0
Modules/signalmodule.c
Modules/signalmodule.c
+13
-0
PC/_subprocess.c
PC/_subprocess.c
+2
-0
No files found.
Doc/library/os.rst
View file @
eb24d749
...
...
@@ -1491,7 +1491,14 @@ written in Python, such as a mail server's external command delivery program.
Send signal *sig* to the process *pid*. Constants for the specific signals
available on the host platform are defined in the :mod:`signal` module.
Availability: Unix.
Windows: The :data:`signal.CTRL_C_EVENT` and
:data:`signal.CTRL_BREAK_EVENT` signals are special signals which can
only be sent to console processes which share a common console window,
e.g., some subprocesses. Any other value for *sig* will cause the process
to be unconditionally killed by the TerminateProcess API, and the exit code
will be set to *sig*. The Windows version of :func:`kill` additionally takes
process handles to be killed.
.. function:: killpg(pgid, sig)
...
...
Doc/library/signal.rst
View file @
eb24d749
...
...
@@ -74,6 +74,20 @@ The variables defined in the :mod:`signal` module are:
the system are defined by this module.
.. data:: CTRL_C_EVENT
The signal corresponding to the CTRL+C keystroke event.
Availability: Windows.
.. data:: CTRL_BREAK_EVENT
The signal corresponding to the CTRL+BREAK keystroke event.
Availability: Windows.
.. data:: NSIG
One more than the number of the highest signal number.
...
...
Doc/library/subprocess.rst
View file @
eb24d749
...
...
@@ -373,8 +373,9 @@ Instances of the :class:`Popen` class have the following methods:
.. note::
On Windows only SIGTERM is supported so far. It's an alias for
:meth:`terminate`.
On Windows, SIGTERM is an alias for :meth:`terminate`. CTRL_C_EVENT and
CTRL_BREAK_EVENT can be sent to processes started with a `creationflags`
parameter which includes `CREATE_NEW_PROCESS_GROUP`.
.. method:: Popen.terminate()
...
...
Lib/subprocess.py
View file @
eb24d749
...
...
@@ -980,6 +980,10 @@ class Popen(object):
"""
if
sig
==
signal
.
SIGTERM
:
self
.
terminate
()
elif
sig
==
signal
.
CTRL_C_EVENT
:
os
.
kill
(
self
.
pid
,
signal
.
CTRL_C_EVENT
)
elif
sig
==
signal
.
CTRL_BREAK_EVENT
:
os
.
kill
(
self
.
pid
,
signal
.
CTRL_BREAK_EVENT
)
else
:
raise
ValueError
(
"Only SIGTERM is supported on Windows"
)
...
...
Lib/test/test_os.py
View file @
eb24d749
...
...
@@ -7,9 +7,13 @@ import errno
import
unittest
import
warnings
import
sys
import
signal
import
subprocess
import
time
import
shutil
from
test
import
support
# Tests creating TESTFN
class
FileTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
...
...
@@ -739,7 +743,6 @@ if sys.platform != 'win32':
def
test_setreuid_neg1
(
self
):
# Needs to accept -1. We run this in a subprocess to avoid
# altering the test runner's process state (issue8045).
import
subprocess
subprocess
.
check_call
([
sys
.
executable
,
'-c'
,
'import os,sys;os.setreuid(-1,-1);sys.exit(0)'
])
...
...
@@ -754,7 +757,6 @@ if sys.platform != 'win32':
def
test_setregid_neg1
(
self
):
# Needs to accept -1. We run this in a subprocess to avoid
# altering the test runner's process state (issue8045).
import
subprocess
subprocess
.
check_call
([
sys
.
executable
,
'-c'
,
'import os,sys;os.setregid(-1,-1);sys.exit(0)'
])
...
...
@@ -798,6 +800,63 @@ else:
class
Pep383Tests
(
unittest
.
TestCase
):
pass
@
unittest
.
skipUnless
(
sys
.
platform
==
"win32"
,
"Win32 specific tests"
)
class
Win32KillTests
(
unittest
.
TestCase
):
def
_kill
(
self
,
sig
,
*
args
):
# Send a subprocess a signal (or in some cases, just an int to be
# the return value)
proc
=
subprocess
.
Popen
(
*
args
)
os
.
kill
(
proc
.
pid
,
sig
)
self
.
assertEqual
(
proc
.
wait
(),
sig
)
def
test_kill_sigterm
(
self
):
# SIGTERM doesn't mean anything special, but make sure it works
self
.
_kill
(
signal
.
SIGTERM
,
[
sys
.
executable
])
def
test_kill_int
(
self
):
# os.kill on Windows can take an int which gets set as the exit code
self
.
_kill
(
100
,
[
sys
.
executable
])
def
_kill_with_event
(
self
,
event
,
name
):
# Run a script which has console control handling enabled.
proc
=
subprocess
.
Popen
([
sys
.
executable
,
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
"win_console_handler.py"
)],
creationflags
=
subprocess
.
CREATE_NEW_PROCESS_GROUP
)
# Let the interpreter startup before we send signals. See #3137.
time
.
sleep
(
0.5
)
os
.
kill
(
proc
.
pid
,
event
)
# proc.send_signal(event) could also be done here.
# Allow time for the signal to be passed and the process to exit.
time
.
sleep
(
0.5
)
if
not
proc
.
poll
():
# Forcefully kill the process if we weren't able to signal it.
os
.
kill
(
proc
.
pid
,
signal
.
SIGINT
)
self
.
fail
(
"subprocess did not stop on {}"
.
format
(
name
))
@
unittest
.
skip
(
"subprocesses aren't inheriting CTRL+C property"
)
def
test_CTRL_C_EVENT
(
self
):
from
ctypes
import
wintypes
import
ctypes
# Make a NULL value by creating a pointer with no argument.
NULL
=
ctypes
.
POINTER
(
ctypes
.
c_int
)()
SetConsoleCtrlHandler
=
ctypes
.
windll
.
kernel32
.
SetConsoleCtrlHandler
SetConsoleCtrlHandler
.
argtypes
=
(
ctypes
.
POINTER
(
ctypes
.
c_int
),
wintypes
.
BOOL
)
SetConsoleCtrlHandler
.
restype
=
wintypes
.
BOOL
# Calling this with NULL and FALSE causes the calling process to
# handle CTRL+C, rather than ignore it. This property is inherited
# by subprocesses.
SetConsoleCtrlHandler
(
NULL
,
0
)
self
.
_kill_with_event
(
signal
.
CTRL_C_EVENT
,
"CTRL_C_EVENT"
)
def
test_CTRL_BREAK_EVENT
(
self
):
self
.
_kill_with_event
(
signal
.
CTRL_BREAK_EVENT
,
"CTRL_BREAK_EVENT"
)
def
test_main
():
support
.
run_unittest
(
ArgTests
,
...
...
@@ -812,7 +871,8 @@ def test_main():
Win32ErrorTests
,
TestInvalidFD
,
PosixUidGidTests
,
Pep383Tests
Pep383Tests
,
Win32KillTests
)
if
__name__
==
"__main__"
:
...
...
Lib/test/win_console_handler.py
0 → 100644
View file @
eb24d749
"""Script used to test os.kill on Windows, for issue #1220212
This script is started as a subprocess in test_os and is used to test the
CTRL_C_EVENT and CTRL_BREAK_EVENT signals, which requires a custom handler
to be written into the kill target.
See http://msdn.microsoft.com/en-us/library/ms685049%28v=VS.85%29.aspx for a
similar example in C.
"""
from
ctypes
import
wintypes
import
signal
import
ctypes
# Function prototype for the handler function. Returns BOOL, takes a DWORD.
HandlerRoutine
=
wintypes
.
WINFUNCTYPE
(
wintypes
.
BOOL
,
wintypes
.
DWORD
)
def
_ctrl_handler
(
sig
):
"""Handle a sig event and return 0 to terminate the process"""
if
sig
==
signal
.
CTRL_C_EVENT
:
pass
elif
sig
==
signal
.
CTRL_BREAK_EVENT
:
pass
else
:
print
(
"UNKNOWN EVENT"
)
return
0
ctrl_handler
=
HandlerRoutine
(
_ctrl_handler
)
SetConsoleCtrlHandler
=
ctypes
.
windll
.
kernel32
.
SetConsoleCtrlHandler
SetConsoleCtrlHandler
.
argtypes
=
(
HandlerRoutine
,
wintypes
.
BOOL
)
SetConsoleCtrlHandler
.
restype
=
wintypes
.
BOOL
if
__name__
==
"__main__"
:
# Add our console control handling function with value 1
if
not
SetConsoleCtrlHandler
(
ctrl_handler
,
1
):
print
(
"Unable to add SetConsoleCtrlHandler"
)
exit
(
-
1
)
# Do nothing but wait for the signal
while
True
:
pass
Lib/unittest/test/test_break.py
View file @
eb24d749
import
gc
import
io
import
os
import
sys
import
signal
import
weakref
...
...
@@ -8,6 +9,7 @@ import unittest
@
unittest
.
skipUnless
(
hasattr
(
os
,
'kill'
),
"Test requires os.kill"
)
@
unittest
.
skipIf
(
sys
.
platform
==
"win32"
,
"Test cannot run on Windows"
)
class
TestBreak
(
unittest
.
TestCase
):
def
setUp
(
self
):
...
...
Modules/posixmodule.c
View file @
eb24d749
...
...
@@ -4171,6 +4171,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
...
...
@@ -7200,6 +7247,7 @@ static PyMethodDef posix_methods[] = {
#endif
/* HAVE_PLOCK */
#ifdef MS_WINDOWS
{
"startfile"
,
win32_startfile
,
METH_VARARGS
,
win32_startfile__doc__
},
{
"kill"
,
win32_kill
,
METH_VARARGS
,
win32_kill__doc__
},
#endif
#ifdef HAVE_SETUID
{
"setuid"
,
posix_setuid
,
METH_VARARGS
,
posix_setuid__doc__
},
...
...
Modules/signalmodule.c
View file @
eb24d749
...
...
@@ -7,6 +7,7 @@
#include "intrcheck.h"
#ifdef MS_WINDOWS
#include <Windows.h>
#ifdef HAVE_PROCESS_H
#include <process.h>
#endif
...
...
@@ -805,6 +806,18 @@ PyInit_signal(void)
PyDict_SetItemString
(
d
,
"ItimerError"
,
ItimerError
);
#endif
#ifdef CTRL_C_EVENT
x
=
PyLong_FromLong
(
CTRL_C_EVENT
);
PyDict_SetItemString
(
d
,
"CTRL_C_EVENT"
,
x
);
Py_DECREF
(
x
);
#endif
#ifdef CTRL_BREAK_EVENT
x
=
PyLong_FromLong
(
CTRL_BREAK_EVENT
);
PyDict_SetItemString
(
d
,
"CTRL_BREAK_EVENT"
,
x
);
Py_DECREF
(
x
);
#endif
if
(
PyErr_Occurred
())
{
Py_DECREF
(
m
);
m
=
NULL
;
...
...
PC/_subprocess.c
View file @
eb24d749
...
...
@@ -599,5 +599,7 @@ PyInit__subprocess()
defint
(
d
,
"INFINITE"
,
INFINITE
);
defint
(
d
,
"WAIT_OBJECT_0"
,
WAIT_OBJECT_0
);
defint
(
d
,
"CREATE_NEW_CONSOLE"
,
CREATE_NEW_CONSOLE
);
defint
(
d
,
"CREATE_NEW_PROCESS_GROUP"
,
CREATE_NEW_PROCESS_GROUP
);
return
m
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment