Amaury Forgeot d'Arc avatar Amaury Forgeot d'Arc committed 964669b

ctypes: implement the new "use_errno" protocol.

Comments (0)

Files changed (3)

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?

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

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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.