[pypy-commit] pypy msvcrt-cffi: fixes

arigo pypy.commits at gmail.com
Sun Jul 17 07:07:58 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: msvcrt-cffi
Changeset: r85735:82aed8c45e31
Date: 2016-07-17 12:57 +0200
http://bitbucket.org/pypy/pypy/changeset/82aed8c45e31/

Log:	fixes

diff --git a/lib_pypy/_subprocess.py b/lib_pypy/_subprocess.py
--- a/lib_pypy/_subprocess.py
+++ b/lib_pypy/_subprocess.py
@@ -22,25 +22,28 @@
     code, message = _ffi.getwinerror()
     raise WindowsError(code, message)
 
-class _handle:
-    def __init__(self, handle):
-        self.handle = handle
+_INVALID_HANDLE_VALUE = _ffi.cast("HANDLE", -1)
+
+class _handle(object):
+    def __init__(self, c_handle):
+        # 'c_handle' is a cffi cdata of type HANDLE, which is basically 'void *'
+        self.c_handle = _ffi.gc(c_handle, _kernel32.CloseHandle)
 
     def __int__(self):
-        return self.handle
-
-    def __del__(self):
-        if self.handle is not None:
-            _kernel32.CloseHandle(self.handle)
+        return int(_ffi.cast("intptr_t", self.c_handle))
 
     def Detach(self):
-        handle, self.handle = self.handle, None
-        return handle
+        h = int(self)
+        if h != -1:
+            _ffi.gc(None, self.c_handle)
+            self.c_handle = _INVALID_HANDLE_VALUE
+        return h
 
     def Close(self):
-        if self.handle not in (-1, None):
-            _kernel32.CloseHandle(self.handle)
-            self.handle = None
+        if int(self) != -1:
+            _kernel32.CloseHandle(self.c_handle)
+            _ffi.gc(None, self.c_handle)
+            self.c_handle = _INVALID_HANDLE_VALUE
 
 def CreatePipe(attributes, size):
     handles = _ffi.new("HANDLE[2]")
@@ -56,10 +59,13 @@
     return _handle(_kernel32.GetCurrentProcess())
 
 def DuplicateHandle(source_process, source, target_process, access, inherit, options=0):
+    # CPython: the first three arguments are expected to be integers
     target = _ffi.new("HANDLE[1]")
 
     res = _kernel32.DuplicateHandle(
-        int(source_process), int(source), int(target_process),
+        _ffi.cast("HANDLE", source_process),
+        _ffi.cast("HANDLE", source),
+        _ffi.cast("HANDLE", target_process),
         target, access, inherit, options)
 
     if not res:
@@ -73,12 +79,13 @@
     if startup_info is not None:
         si.dwFlags = startup_info.dwFlags
         si.wShowWindow = startup_info.wShowWindow
+        # CPython: these three handles are expected to be _handle objects
         if startup_info.hStdInput:
-            si.hStdInput = int(startup_info.hStdInput)
+            si.hStdInput = startup_info.hStdInput.c_handle
         if startup_info.hStdOutput:
-            si.hStdOutput = int(startup_info.hStdOutput)
+            si.hStdOutput = startup_info.hStdOutput.c_handle
         if startup_info.hStdError:
-            si.hStdError = int(startup_info.hStdError)
+            si.hStdError = startup_info.hStdError.c_handle
 
     pi = _ffi.new("PROCESS_INFORMATION *")
 
@@ -122,18 +129,22 @@
     return code[0]
 
 def TerminateProcess(handle, exitcode):
-    exitcode = _ffi.cast("UINT", exitcode)
-    res = _kernel32.TerminateProcess(int(handle), exitcode)
+    # CPython: the first argument is expected to be an integer.
+    # The second argument is silently wrapped in a UINT.
+    res = _kernel32.TerminateProcess(_ffi.cast("HANDLE", handle),
+                                     _ffi.cast("UINT", exitcode))
 
     if not res:
         raise _WinError()
 
 def GetStdHandle(stdhandle):
+    stdhandle = _ffi.cast("DWORD", stdhandle)
     res = _kernel32.GetStdHandle(stdhandle)
 
     if not res:
         return None
     else:
+        # note: returns integer, not handle object
         return res
 
 STD_INPUT_HANDLE = -10


More information about the pypy-commit mailing list