Commits

Armin Rigo  committed 1deba92 Merge

hg merge default

  • Participants
  • Parent commits bfadfd7, c0342ec
  • Branches stm-thread

Comments (0)

Files changed (15)

File pypy/doc/whatsnew-1.9.rst

 Many bugs were corrected for windows 32 bit. New functionality was added to
 test validity of file descriptors, leading to the removal of the  global 
 _invalid_parameter_handler
+.. branch: win32-kill
+Add os.kill to windows even if translating python does not have os.kill
 .. branch: win64-stage1
 .. branch: zlib-mem-pressure
 

File pypy/module/__pypy__/__init__.py

 from pypy.interpreter.mixedmodule import MixedModule
 from pypy.module.imp.importing import get_pyc_magic
 
-
 class BuildersModule(MixedModule):
     appleveldefs = {}
 
         'lookup_special'            : 'interp_magic.lookup_special',
         'do_what_I_mean'            : 'interp_magic.do_what_I_mean',
         'list_strategy'             : 'interp_magic.list_strategy',
+        'validate_fd'               : 'interp_magic.validate_fd',
     }
 
     submodules = {

File pypy/module/__pypy__/interp_magic.py

 from pypy.interpreter.baseobjspace import ObjSpace, W_Root
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, wrap_oserror
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.objspace.std.typeobject import MethodCache
 from pypy.objspace.std.mapdict import IndexCache
+from pypy.rlib import rposix
 
 def internal_repr(space, w_object):
     return space.wrap('%r' % (w_object,))
     else:
         w_msg = space.wrap("Can only get the list strategy of a list")
         raise OperationError(space.w_TypeError, w_msg)
+
+@unwrap_spec(fd='c_int')
+def validate_fd(space, fd):
+    try:
+        rposix.validate_fd(fd)
+    except OSError, e:
+        raise wrap_oserror(space, e)

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/app_posix.py

 # NOT_RPYTHON
 
 from _structseq import structseqtype, structseqfield
+from __pypy__ import validate_fd
 
 # XXX we need a way to access the current module's globals more directly...
 import sys
         except IOError, e:
             raise OSError(e.errno, e.strerror, e.filename)
 else:
-    def _validate_fd(fd):
-        # XXX for the moment
-        return
+    _validate_fd = validate_fd
 
 # Capture file.fdopen at import time, as some code replaces
 # __builtins__.file with a custom function.

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/rposix.py

 import os
-from pypy.rpython.lltypesystem.rffi import (CConstant, CExternVariable,
-        INT, CCHARPP)
-from pypy.rpython.lltypesystem import lltype, ll2ctypes, rffi
+from pypy.rpython.lltypesystem.rffi import CConstant, CExternVariable, INT
+from pypy.rpython.lltypesystem import ll2ctypes, rffi
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rlib.rarithmetic import intmask
 from pypy.rlib.objectmodel import specialize
 from pypy.rlib import jit
+from pypy.translator.platform import platform
 
 class CConstantErrno(CConstant):
     # these accessors are used when calling get_errno() or set_errno()
         assert index == 0
         ll2ctypes.TLS.errno = value
 if os.name == 'nt':
+    if platform.name == 'msvc':
+        includes=['errno.h','stdio.h']
+    else:
+        includes=['errno.h','stdio.h', 'stdint.h']
     separate_module_sources =['''
         /* Lifted completely from CPython 3.3 Modules/posix_module.c */
         #include <malloc.h> /* for _msize */
 else:
     separate_module_sources = []
     export_symbols = []
+    includes=['errno.h','stdio.h']
 errno_eci = ExternalCompilationInfo(
-    includes=['errno.h','stdio.h'],
-    separate_module_sources = separate_module_sources,
-    export_symbols = export_symbols,
+    includes=includes,
+    separate_module_sources=separate_module_sources,
+    export_symbols=export_symbols,
 )
 
 _get_errno, _set_errno = CExternVariable(INT, 'errno', errno_eci,

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:

File pypy/rpython/tool/rfficache.py

 
 import py
 import os
-import distutils
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.tool.udir import udir
-from pypy.tool.autopath import pypydir
 from pypy.rlib import rarithmetic
 from pypy.rpython.lltypesystem import lltype
 from pypy.tool.gcc_cache import build_executable_cache
 
 def ask_gcc(question, add_source=""):
+    from pypy.translator.platform import platform
     includes = ['stdlib.h', 'stdio.h', 'sys/types.h']
-    if os.name != 'nt':
+    if platform.name != 'msvc':
         includes += ['inttypes.h']
     include_string = "\n".join(["#include <%s>" % i for i in includes])
     c_source = py.code.Source('''

File pypy/translator/platform/posix.py

 
         if relto:
             response_file = relto.bestrelpath(response_file)
+        if self.cc == 'mingw32' or (self.cc== 'gcc' and os.name=='nt'):    
+            return ["-Wl,--export-all-symbols,--version-script=%s" % \
+                    (response_file,)]
         return ["-Wl,--export-dynamic,--version-script=%s" % (response_file,)]
 
     def _link(self, cc, ofiles, link_args, standalone, exe_name):

File pypy/translator/platform/windows.py

         cc = os.environ.get('CC','')
     if not cc:
         return MsvcPlatform(cc=cc, x64=x64_flag)
-    elif cc.startswith('mingw'):
+    elif cc.startswith('mingw') or cc == 'gcc':
         return MingwPlatform(cc)
     try:
         subprocess.check_output([cc, '--version'])