Added kill, terminate and send_signal to subprocess.Popen
The bits and pieces for the Windows side were already in place. The POSIX side is trivial (as usual) and uses os.kill().
This commit is contained in:
parent
c873550737
commit
e74c8f2879
|
@ -208,6 +208,29 @@ Instances of the :class:`Popen` class have the following methods:
|
|||
size is large or unlimited.
|
||||
|
||||
|
||||
.. method:: Popen.send_signal(signal)
|
||||
|
||||
Sends the signal *signal* to the child.
|
||||
|
||||
.. note::
|
||||
|
||||
On Windows only SIGTERM is supported so far. It's an alias for
|
||||
*terminate*.
|
||||
|
||||
|
||||
.. method:: Popen.terminate()
|
||||
|
||||
Stop the child. On Posix OSs the method sends SIGTERM to the
|
||||
child. On Windows the Win32 API function TerminateProcess is called
|
||||
to stop the child.
|
||||
|
||||
|
||||
.. method:: Popen.kill()
|
||||
|
||||
Kills the child. On Posix OSs the function sends SIGKILL to the child.
|
||||
On Windows *kill* is an alias for *terminate*.
|
||||
|
||||
|
||||
The following attributes are also available:
|
||||
|
||||
.. attribute:: Popen.stdin
|
||||
|
|
|
@ -357,6 +357,7 @@ import os
|
|||
import types
|
||||
import traceback
|
||||
import gc
|
||||
import signal
|
||||
|
||||
# Exception classes used by this module.
|
||||
class CalledProcessError(Exception):
|
||||
|
@ -384,6 +385,7 @@ if mswindows:
|
|||
from win32process import CreateProcess, STARTUPINFO, \
|
||||
GetExitCodeProcess, STARTF_USESTDHANDLES, \
|
||||
STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
|
||||
from win32process import TerminateProcess
|
||||
from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
|
||||
else:
|
||||
from _subprocess import *
|
||||
|
@ -906,6 +908,21 @@ class Popen(object):
|
|||
self.wait()
|
||||
return (stdout, stderr)
|
||||
|
||||
def send_signal(self, sig):
|
||||
"""Send a signal to the process
|
||||
"""
|
||||
if sig == signal.SIGTERM:
|
||||
self.terminate()
|
||||
else:
|
||||
raise ValueError("Only SIGTERM is supported on Windows")
|
||||
|
||||
def terminate(self):
|
||||
"""Terminates the process
|
||||
"""
|
||||
TerminateProcess(self._handle, 1)
|
||||
|
||||
kill = terminate
|
||||
|
||||
else:
|
||||
#
|
||||
# POSIX methods
|
||||
|
@ -1184,6 +1201,21 @@ class Popen(object):
|
|||
self.wait()
|
||||
return (stdout, stderr)
|
||||
|
||||
def send_signal(self, sig):
|
||||
"""Send a signal to the process
|
||||
"""
|
||||
os.kill(self.pid, sig)
|
||||
|
||||
def terminate(self):
|
||||
"""Terminate the process with SIGTERM
|
||||
"""
|
||||
self.send_signal(signal.SIGTERM)
|
||||
|
||||
def kill(self):
|
||||
"""Kill the process with SIGKILL
|
||||
"""
|
||||
self.send_signal(signal.SIGKILL)
|
||||
|
||||
|
||||
def _demo_posix():
|
||||
#
|
||||
|
|
|
@ -584,6 +584,29 @@ class ProcessTestCase(unittest.TestCase):
|
|||
os.remove(fname)
|
||||
self.assertEqual(rc, 47)
|
||||
|
||||
def test_send_signal(self):
|
||||
p = subprocess.Popen([sys.executable,
|
||||
"-c", "input()"])
|
||||
|
||||
self.assert_(p.poll() is None, p.poll())
|
||||
p.send_signal(signal.SIGINT)
|
||||
self.assertNotEqual(p.wait(), 0)
|
||||
|
||||
def test_kill(self):
|
||||
p = subprocess.Popen([sys.executable,
|
||||
"-c", "input()"])
|
||||
|
||||
self.assert_(p.poll() is None, p.poll())
|
||||
p.kill()
|
||||
self.assertEqual(p.wait(), -signal.SIGKILL)
|
||||
|
||||
def test_terminate(self):
|
||||
p = subprocess.Popen([sys.executable,
|
||||
"-c", "input()"])
|
||||
|
||||
self.assert_(p.poll() is None, p.poll())
|
||||
p.terminate()
|
||||
self.assertEqual(p.wait(), -signal.SIGTERM)
|
||||
|
||||
#
|
||||
# Windows tests
|
||||
|
@ -655,6 +678,29 @@ class ProcessTestCase(unittest.TestCase):
|
|||
' -c "import sys; sys.exit(47)"')
|
||||
self.assertEqual(rc, 47)
|
||||
|
||||
def test_send_signal(self):
|
||||
p = subprocess.Popen([sys.executable,
|
||||
"-c", "input()"])
|
||||
|
||||
self.assert_(p.poll() is None, p.poll())
|
||||
p.send_signal(signal.SIGTERM)
|
||||
self.assertNotEqual(p.wait(), 0)
|
||||
|
||||
def test_kill(self):
|
||||
p = subprocess.Popen([sys.executable,
|
||||
"-c", "input()"])
|
||||
|
||||
self.assert_(p.poll() is None, p.poll())
|
||||
p.kill()
|
||||
self.assertNotEqual(p.wait(), 0)
|
||||
|
||||
def test_terminate(self):
|
||||
p = subprocess.Popen([sys.executable,
|
||||
"-c", "input()"])
|
||||
|
||||
self.assert_(p.poll() is None, p.poll())
|
||||
p.terminate()
|
||||
self.assertNotEqual(p.wait(), 0)
|
||||
|
||||
def test_main():
|
||||
test_support.run_unittest(ProcessTestCase)
|
||||
|
|
Loading…
Reference in New Issue