Commits

mattip  committed 84e5827 Merge

merge win32-kill branch

  • Participants
  • Parent commits be43c49, d5cc709

Comments (0)

Files changed (7)

File pypy/module/posix/__init__.py

     '_exit'     : 'interp_posix._exit',
     'utime'     : 'interp_posix.utime',
     '_statfields': 'interp_posix.getstatfields(space)',
+    'kill'      : 'interp_posix.kill',
+    'abort'     : 'interp_posix.abort',
     }
 
     if os.name == 'nt':
         interpleveldefs['putenv'] = 'interp_posix.putenv'
     if hasattr(posix, 'unsetenv'): # note: emulated in os
         interpleveldefs['unsetenv'] = 'interp_posix.unsetenv'
-    if hasattr(os, 'kill') and sys.platform != 'win32':
-        interpleveldefs['kill'] = 'interp_posix.kill'
-        interpleveldefs['abort'] = 'interp_posix.abort'
     if hasattr(os, 'killpg'):
         interpleveldefs['killpg'] = 'interp_posix.killpg'
     if hasattr(os, 'getpid'):

File pypy/module/posix/interp_posix.py

 from pypy.interpreter.error import operationerrfmt
 from pypy.rpython.module.ll_os import RegisterOs
 from pypy.rpython.module import ll_os_stat
+from pypy.rlib import rwin32
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 def kill(space, pid, sig):
     "Kill a process with a signal."
     try:
-        os.kill(pid, sig)
+        rwin32.os_kill(pid, sig)
     except OSError, e:
         raise wrap_oserror(space, e)
 
     """Abort the interpreter immediately.  This 'dumps core' or otherwise fails
 in the hardest way possible on the hosting operating system."""
     import signal
-    os.kill(os.getpid(), signal.SIGABRT)
+    rwin32.os_kill(os.getpid(), signal.SIGABRT)
 
 @unwrap_spec(src='str0', dst='str0')
 def link(space, src, dst):

File pypy/module/posix/test/test_posix2.py

             # not to some code inside app_posix.py
             assert w[-1].lineno == f_tmpnam_warning.func_code.co_firstlineno
 
+    def test_has_kill(self):
+        import os
+        assert hasattr(os, 'kill')
 
 class AppTestEnvironment(object):
     def setup_class(cls):

File pypy/rlib/rwin32.py

                        MAX_PATH
                        WAIT_OBJECT_0 WAIT_TIMEOUT INFINITE
                        ERROR_INVALID_HANDLE
+                       DELETE READ_CONTROL SYNCHRONIZE WRITE_DAC
+                       WRITE_OWNER PROCESS_ALL_ACCESS
+                       PROCESS_CREATE_PROCESS PROCESS_CREATE_THREAD
+                       PROCESS_DUP_HANDLE PROCESS_QUERY_INFORMATION
+                       PROCESS_QUERY_LIMITED_INFORMATION 
+                       PROCESS_SET_QUOTA
+                       PROCESS_SUSPEND_RESUME PROCESS_TERMINATE
+                       PROCESS_VM_OPERATION PROCESS_VM_READ
+                       PROCESS_VM_WRITE
+                       CTRL_C_EVENT CTRL_BREAK_EVENT
                     """.split():
             locals()[name] = rffi_platform.ConstantInteger(name)
 
         'SetEvent', [HANDLE], BOOL)
     ResetEvent = winexternal(
         'ResetEvent', [HANDLE], BOOL)
+    _OpenProcess = winexternal(
+        'OpenProcess', [DWORD, BOOL, DWORD], HANDLE)
+    def OpenProcess(*args):
+        ''' OpenProcess( dwDesiredAccess, bInheritHandle, dwProcessId)
+        where dwDesiredAccess is a combination of the flags:
+        DELETE (0x00010000L)
+        READ_CONTROL (0x00020000L)
+        SYNCHRONIZE (0x00100000L)
+        WRITE_DAC (0x00040000L)
+        WRITE_OWNER (0x00080000L)
 
+        PROCESS_ALL_ACCESS
+        PROCESS_CREATE_PROCESS (0x0080)
+        PROCESS_CREATE_THREAD (0x0002)
+        PROCESS_DUP_HANDLE (0x0040)
+        PROCESS_QUERY_INFORMATION (0x0400)
+        PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
+        PROCESS_SET_QUOTA (0x0100)
+        PROCESS_SUSPEND_RESUME (0x0800)
+        PROCESS_TERMINATE (0x0001)
+        PROCESS_VM_OPERATION (0x0008)
+        PROCESS_VM_READ (0x0010)
+        PROCESS_VM_WRITE (0x0020)
+        SYNCHRONIZE (0x00100000L)
+        '''
+        handle = _OpenProcess(*args)
+        if handle == NULL_HANDLE:
+            raise lastWindowsError("OpenProcess")
+        return handle
+    TerminateProcess = winexternal(
+        'TerminateProcess', [HANDLE, rffi.UINT], BOOL)
+    GenerateConsoleCtrlEvent = winexternal(
+        'GenerateConsoleCtrlEvent', [DWORD, DWORD], BOOL)
+    _GetCurrentProcessId = winexternal(
+        'GetCurrentProcessId', [], DWORD)
+    def GetCurrentProcessId():
+        return rffi.cast(lltype.Signed, _GetCurrentProcessId())
+    def os_kill(pid, sig):
+        if sig == CTRL_C_EVENT or sig == CTRL_BREAK_EVENT:
+            if GenerateConsoleCtrlEvent(sig, pid) == 0:
+                raise lastWindowsError('os_kill failed generating event')
+        handle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
+        if handle == NULL_HANDLE:
+            raise lastWindowsError('os_kill failed opening process')
+        t = TerminateProcess(handle, sig)
+        if t == 0:
+            err = lastWindowsError('os_kill failed to terminate process')
+            CloseHandle(handle)
+            raise err
+        t = CloseHandle(handle)
+        if t == 0:
+            raise lastWindowsError('os_kill after terminating process,'
+                     ' while closing handle') 
+else:
+    #not win32
+    os_kill = os.kill

File pypy/rlib/test/test_rwin32.py

     rwin32.validate_fd = validate_fd
     raises(WindowsError, rwin32.get_osfhandle, fd)
     rwin32.validate_fd = _validate_fd
+
+def test_open_process():
+    pid = rwin32.GetCurrentProcessId()
+    assert pid != 0
+    handle = rwin32.OpenProcess(rwin32.PROCESS_QUERY_INFORMATION, False, pid)
+    rwin32.CloseHandle(handle)
+    raises(WindowsError, rwin32.OpenProcess, rwin32.PROCESS_TERMINATE, False, 0)
+
+def test_terminate_process():
+    import subprocess, signal, sys
+    proc = subprocess.Popen([sys.executable, "-c",
+                         "import time;"
+                         "time.sleep(10)",
+                         ],
+                        ) 
+    print proc.pid
+    handle = rwin32.OpenProcess(rwin32.PROCESS_ALL_ACCESS, False, proc.pid)
+    assert rwin32.TerminateProcess(handle, signal.SIGTERM) == 0
+    rwin32.CloseHandle(handle)
+    assert proc.wait() == signal.SIGTERM
+ 

File pypy/rpython/module/ll_os.py

 
 import os, sys, errno
 import py
-from pypy.rpython.module.support import ll_strcpy, OOSupport
-from pypy.tool.sourcetools import func_with_new_name, func_renamer
+from pypy.rpython.module.support import OOSupport
+from pypy.tool.sourcetools import func_renamer
 from pypy.rlib.rarithmetic import r_longlong
 from pypy.rpython.extfunc import (
-    BaseLazyRegistering, lazy_register, register_external)
+    BaseLazyRegistering, register_external)
 from pypy.rpython.extfunc import registering, registering_if, extdef
 from pypy.annotation.model import (
     SomeInteger, SomeString, SomeTuple, SomeFloat, SomeUnicodeString)
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.tool import rffi_platform as platform
 from pypy.rlib import rposix
-from pypy.tool.udir import udir
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.rpython.lltypesystem.rstr import mallocstr
-from pypy.rpython.annlowlevel import llstr
-from pypy.rpython.lltypesystem.llmemory import sizeof,\
-     itemoffsetof, cast_ptr_to_adr, cast_adr_to_ptr, offsetof
+from pypy.rpython.lltypesystem.llmemory import itemoffsetof, offsetof
 from pypy.rpython.lltypesystem.rstr import STR
-from pypy.rpython.annlowlevel import llstr
-from pypy.rlib import rgc
 from pypy.rlib.objectmodel import specialize
 
 str0 = SomeString(no_nul=True)
 unicode0 = SomeUnicodeString(no_nul=True)
 
-
 def monkeypatch_rposix(posixfunc, unicodefunc, signature):
     func_name = posixfunc.__name__
 
     def register_os_kill(self):
         os_kill = self.llexternal('kill', [rffi.PID_T, rffi.INT],
                                   rffi.INT)
-
         def kill_llimpl(pid, sig):
             res = rffi.cast(lltype.Signed, os_kill(rffi.cast(rffi.PID_T, pid),
                                                    rffi.cast(rffi.INT, sig)))
             if res < 0:
                 raise OSError(rposix.get_errno(), "os_kill failed")
-
         return extdef([int, int], s_None, llimpl=kill_llimpl,
                       export_name="ll_os.ll_os_kill")
 

File pypy/rpython/module/test/test_ll_os.py

 
 
 def test_os_kill():
-    try:
-        f = getllimpl(os.kill)
-    except:
+    if not hasattr(os,'kill') or sys.platform == 'win32':
         skip('No kill in os')
+    f = getllimpl(os.kill)
     import subprocess
     import signal
     proc = subprocess.Popen([sys.executable, "-c",
                         )
     f(proc.pid, signal.SIGTERM)
     expected = -signal.SIGTERM
-    if sys.platform.startswith('win'):
-        expected = -expected
     assert proc.wait() == expected
 
 class ExpectTestOs: