[pypy-commit] cffi default: Fix ffi.dlopen(None): we can't replace it with ffi.dlopen("c") on POSIX

arigo noreply at buildbot.pypy.org
Fri Feb 28 10:38:15 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r1466:90be5bcd6bc8
Date: 2014-02-28 10:37 +0100
http://bitbucket.org/cffi/cffi/changeset/90be5bcd6bc8/

Log:	Fix ffi.dlopen(None): we can't replace it with ffi.dlopen("c") on
	POSIX systems. It has a different meaning: getting a handle that
	works for
	*any* already-loaded library, not just "libc.so". This breaks
	obscurely a test that is already obscure, so ignoring that (I
	checked that in C it would break the same way anyway).

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -1,4 +1,4 @@
-import types
+import sys, types
 from .lock import allocate_lock
 
 try:
@@ -389,22 +389,27 @@
         return self._backend.from_handle(x)
 
 
-def _make_ffi_library(ffi, libname, flags):
-    import os
-    name = libname
+def _load_backend_lib(backend, name, flags):
     if name is None:
-        name = 'c'    # on Posix only
-    backend = ffi._backend
+        if sys.platform != "win32":
+            return backend.load_library(None, flags)
+        name = "c"    # Windows: load_library(None) fails, but this works
+                      # (backward compatibility hack only)
     try:
         if '.' not in name and '/' not in name:
             raise OSError("library not found: %r" % (name,))
-        backendlib = backend.load_library(name, flags)
+        return backend.load_library(name, flags)
     except OSError:
         import ctypes.util
         path = ctypes.util.find_library(name)
         if path is None:
             raise     # propagate the original OSError
-        backendlib = backend.load_library(path, flags)
+        return backend.load_library(path, flags)
+
+def _make_ffi_library(ffi, libname, flags):
+    import os
+    backend = ffi._backend
+    backendlib = _load_backend_lib(backend, libname, flags)
     copied_enums = []
     #
     def make_accessor_locked(name):
diff --git a/testing/test_function.py b/testing/test_function.py
--- a/testing/test_function.py
+++ b/testing/test_function.py
@@ -250,22 +250,14 @@
             py.test.skip("probably no symbol 'stdout' in the lib")
         ffi = FFI(backend=self.Backend())
         ffi.cdef("""
-            int puts(const char *);
-            void *stdout, *stderr;
+            void *stdout;
         """)
-        ffi.C = ffi.dlopen(None)
-        pout = ffi.C.stdout
-        perr = ffi.C.stderr
-        assert repr(pout).startswith("<cdata 'void *' 0x")
-        assert repr(perr).startswith("<cdata 'void *' 0x")
-        with FdWriteCapture(2) as fd:     # capturing stderr
-            ffi.C.stdout = perr
-            try:
-                ffi.C.puts(b"hello!") # goes to stdout, which is equal to stderr now
-            finally:
-                ffi.C.stdout = pout
-        res = fd.getvalue()
-        assert res == b"hello!\n"
+        C = ffi.dlopen(None)
+        pout = C.stdout
+        C.stdout = ffi.NULL
+        assert C.stdout == ffi.NULL
+        C.stdout = pout
+        assert C.stdout == pout
 
     def test_strchr(self):
         ffi = FFI(backend=self.Backend())
diff --git a/testing/test_parsing.py b/testing/test_parsing.py
--- a/testing/test_parsing.py
+++ b/testing/test_parsing.py
@@ -11,9 +11,9 @@
 
     def load_library(self, name, flags):
         if sys.platform == 'win32':
-            assert "msvcr" in name
+            assert name is None or "msvcr" in name
         else:
-            assert "libc" in name or "libm" in name
+            assert name is None or "libc" in name or "libm" in name
         return FakeLibrary()
 
     def new_function_type(self, args, result, has_varargs):


More information about the pypy-commit mailing list