Commits

Amaury Forgeot d'Arc committed 964669b

ctypes: implement the new "use_errno" protocol.

  • Participants
  • Parent commits ab15ce4
  • Branches fast-forward

Comments (0)

Files changed (3)

File lib_pypy/_ctypes/__init__.py

 
 from _rawffi import FUNCFLAG_STDCALL, FUNCFLAG_CDECL, FUNCFLAG_PYTHONAPI
 from _rawffi import FUNCFLAG_USE_ERRNO, FUNCFLAG_USE_LASTERROR
-from _rawffi import get_errno, set_errno
 
+from _ctypes.builtin import get_errno, set_errno
 if _os.name in ("nt", "ce"):
-    from _rawffi import get_last_error, set_last_error
+    from _ctypes.builtin import get_last_error, set_last_error
 
 __version__ = '1.1.0'
 #XXX platform dependant?

File lib_pypy/_ctypes/builtin.py

 
 import _rawffi, sys
+import threading
 
 class ConvMode:
     encoding = 'ascii'
     cobj = ctypes.c_void_p.from_param(addr)
     arg = cobj._get_buffer_value()
     return _rawffi.wcharp2rawunicode(arg, lgt)
+
+class ErrorObject(threading.local):
+    def __init__(self):
+        self.errno = 0
+        self.winerror = 0
+_error_object = ErrorObject()
+
+def get_errno():
+    return _error_object.errno
+
+def set_errno(errno):
+    old_errno = _error_object.errno
+    _error_object.errno = errno
+    return old_errno
+
+def get_last_error():
+    return _error_object.winerror
+
+def set_last_error(winerror):
+    old_winerror = _error_object.winerror
+    _error_object.winerror = winerror
+    return old_winerror

File lib_pypy/_ctypes/function.py

 
 from _ctypes.basics import _CData, _CDataMeta, cdata_from_address
 from _ctypes.basics import ArgumentError, keepalive_key
+from _ctypes.builtin import set_errno, set_last_error
 import _rawffi
 import sys
 import traceback
         
         restype = self._restype_
         funcptr = self._getfuncptr(argtypes, restype, thisarg)
-        resbuffer = funcptr(*[arg._get_buffer_for_param()._buffer
-                              for arg in args])
+        if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
+            set_errno(_rawffi.get_errno())
+        if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
+            set_last_error(_rawffi.get_last_error())
+        try:
+            resbuffer = funcptr(*[arg._get_buffer_for_param()._buffer
+                                  for arg in args])
+        finally:
+            if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
+                set_errno(_rawffi.get_errno())
+            if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
+                set_last_error(_rawffi.get_last_error())
         result = self._build_result(restype, resbuffer, argtypes, args)
 
         # The 'errcheck' protocol