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.
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 59ed60c..e4c843d 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -990,6 +990,10 @@
             """
             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")
 
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 4e21dd8..2fc0d07 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -7,6 +7,9 @@
 import unittest
 import warnings
 import sys
+import signal
+import subprocess
+import time
 from test import test_support
 
 warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, __name__)
@@ -649,7 +652,6 @@
             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)'])
@@ -664,7 +666,6 @@
             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)'])
@@ -672,6 +673,63 @@
     class PosixUidGidTests(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.1)
+        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.1)
+        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():
     test_support.run_unittest(
         FileTests,
@@ -684,7 +742,8 @@
         URandomTests,
         Win32ErrorTests,
         TestInvalidFD,
-        PosixUidGidTests
+        PosixUidGidTests,
+        Win32KillTests
     )
 
 if __name__ == "__main__":
diff --git a/Lib/test/win_console_handler.py b/Lib/test/win_console_handler.py
new file mode 100644
index 0000000..e4190d4
--- /dev/null
+++ b/Lib/test/win_console_handler.py
@@ -0,0 +1,42 @@
+"""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

+    input()

diff --git a/Lib/unittest/test/test_break.py b/Lib/unittest/test/test_break.py
index 1cd75b8..c1c5e6d 100644
--- a/Lib/unittest/test/test_break.py
+++ b/Lib/unittest/test/test_break.py
@@ -1,5 +1,6 @@
 import gc
 import os
+import sys
 import signal
 import weakref
 
@@ -10,6 +11,7 @@
 
 
 @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):