[pypy-commit] cffi default: Save and restore 'errno' also across verify()ed functions.

arigo noreply at buildbot.pypy.org
Thu Jun 14 23:41:13 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r360:be319669c70e
Date: 2012-06-14 23:41 +0200
http://bitbucket.org/cffi/cffi/changeset/be319669c70e/

Log:	Save and restore 'errno' also across verify()ed functions.

diff --git a/c/_ffi_backend.c b/c/_ffi_backend.c
--- a/c/_ffi_backend.c
+++ b/c/_ffi_backend.c
@@ -3369,6 +3369,16 @@
     return result;
 }
 
+void _cffi_restore_errno(void)
+{
+    errno = saved_errno;
+}
+
+void _cffi_save_errno(void)
+{
+    saved_errno = errno;
+}
+
 static void *cffi_exports[] = {
     _cffi_to_c_char_p,
     _cffi_to_c_signed_char,
@@ -3388,6 +3398,8 @@
     _cffi_from_c_pointer,
     _cffi_to_c_pointer,
     _cffi_get_struct_layout,
+    _cffi_restore_errno,
+    _cffi_save_errno,
 };
 
 /************************************************************/
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -19,6 +19,7 @@
             return num
 
     def verify(self, preamble, stop_on_warnings=True):
+        # XXX  take **kwds
         modname = ffiplatform.undercffi_module_name()
         filebase = os.path.join(ffiplatform.tmpdir(), modname)
         self.chained_list_constants = None
@@ -195,9 +196,11 @@
                               is_funcarg=True)
             prnt()
         #
+        prnt('  _cffi_restore_errno();')
         prnt('  { %s%s(%s); }' % (
             result_code, name,
             ', '.join(['x%d' % i for i in range(len(tp.args))])))
+        prnt('  _cffi_save_errno();')
         prnt()
         #
         if result_code:
@@ -472,6 +475,10 @@
     ((char *(*)(PyObject *, CTypeDescrObject *))_cffi_exports[11])
 #define _cffi_get_struct_layout                                          \
     ((PyObject *(*)(Py_ssize_t[]))_cffi_exports[12])
+#define _cffi_restore_errno                                              \
+    ((void(*)(void))_cffi_exports[13])
+#define _cffi_save_errno                                                 \
+    ((void(*)(void))_cffi_exports[14])
 
 #if SIZEOF_LONG < SIZEOF_LONG_LONG
 #  define _cffi_to_c_long_long PyLong_AsLongLong
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -319,3 +319,17 @@
     assert str(e.value) == 'in enum ee: EE2 has the real value 2, not 1'
     # extra items cannot be seen and have no bad consequence anyway
     ffi.verify("enum ee { EE1, EE2, EE3, EE4 };")
+
+def test_get_set_errno():
+    ffi = FFI()
+    ffi.cdef("int foo(int);")
+    lib = ffi.verify("""
+        static int foo(int x)
+        {
+            errno += 1;
+            return x * 7;
+        }
+    """)
+    ffi.errno = 15
+    assert lib.foo(6) == 42
+    assert ffi.errno == 16


More information about the pypy-commit mailing list