This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Michael.Felt
Recipients Michael.Felt, aixtools@gmail.com, martin.panter
Date 2016-09-28.14:39:25
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1475073568.44.0.800105651379.issue27435@psf.upfronthosting.co.za>
In-reply-to
Content
The "core" changes in this patch are very simple - in parallel with the way find_library() is managed in util.py



a) __init__.py:
   add an additional mode bit for call to dlopen() (in __init__.py)
diff -u src/Python-2.7.12/Lib/ctypes/__init__.py python-2.7.12.2/Lib/ctypes/__init__.py
--- src/Python-2.7.12/Lib/ctypes/__init__.py    2016-06-25 21:49:30 +0000
+++ python-2.7.12.2/Lib/ctypes/__init__.py      2016-09-28 12:55:15 +0000
@@ -352,6 +352,16 @@
             flags |= _FUNCFLAG_USE_ERRNO
         if use_last_error:
             flags |= _FUNCFLAG_USE_LASTERROR
+        if _sys.platform.startswith("aix"):
+            """When the name contains ".a(" and ends with ")",
+               asin "libFOO.a(libFOO.so)" this is taken to be an
+               archive(member) syntax for dlopen(), and the mode is adjusted.
+               Otherwise, name is presented to dlopen() as a file argument.
+            """
+            # from _ctypes import RTLD_NOW - not until Python3.7
+            if name and name.endswith(")") and ".a(" in name:
+                RTLD_MEMBER = 0x00040000
+                mode |= RTLD_MEMBER

         class _FuncPtr(_CFuncPtr):
             _flags_ = flags

b) util.py:
   determine that is is not generic posix and call and import
   and execute an external .py file
c) some prettier (optional!) print statements in self-test

diff -u src/Python-2.7.12/Lib/ctypes/util.py python-2.7.12.2/Lib/ctypes/util.py
--- src/Python-2.7.12/Lib/ctypes/util.py        2016-06-25 21:49:30 +0000
+++ python-2.7.12.2/Lib/ctypes/util.py  2016-09-28 08:41:57 +0000
@@ -81,6 +81,14 @@
                 continue
         return None

+if sys.platform.startswith("aix"):
+    # find .so members in .a files
+    # using dump loader header information + sys.
+    import ctypes._aix as aix
+
+    def find_library(name):
+        return aix.find_library(name)
+
 elif os.name == "posix":
     # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
     import re, tempfile, errno
@@ -247,10 +255,11 @@
         print find_library("msvcrt")

     if os.name == "posix":
-        # find and load_version
-        print find_library("m")
-        print find_library("c")
-        print find_library("bz2")
+        # find
+        print("m\t:: %s" % find_library("m"))
+        print("c\t:: %s" % find_library("c"))
+        print("bz2\t:: %s" % find_library("bz2"))
+        print("crypt\t:: %s" % find_library("crypt"))

         # getattr
 ##        print cdll.m
@@ -262,6 +271,12 @@
             print cdll.LoadLibrary("libcrypto.dylib")
             print cdll.LoadLibrary("libSystem.dylib")
             print cdll.LoadLibrary("System.framework/System")
+        elif sys.platform.startswith("aix"):
+            print("crypto\t:: %s" % cdll.LoadLibrary(find_library("crypto")))
+            if (sys.maxsize < 2**32):
+                print("c\t:: %s" % cdll.LoadLibrary("libc.a(shr.o)"))
+            else:
+                print("c\t:: %s" % cdll.LoadLibrary("libc.a(shr_64.o)"))
         else:
             print cdll.LoadLibrary("libm.so")
             print cdll.LoadLibrary("libcrypt.so")


d) in test_loading.py say test is failed if find_library does not find
   at least one library

diff -u src/Python-2.7.12/Lib/ctypes/test/test_loading.py python-2.7.12.2/Lib/ctypes/test/test_loading.py
--- src/Python-2.7.12/Lib/ctypes/test/test_loading.py   2016-06-25 21:49:30 +0000
+++ python-2.7.12.2/Lib/ctypes/test/test_loading.py     2016-09-28 12:43:46 +0000
@@ -11,6 +11,11 @@
     libc_name = "coredll"
 elif sys.platform == "cygwin":
     libc_name = "cygwin1.dll"
+elif sys.platform.startswith("aix"):
+    if (sys.maxsize < 2**32):
+        libc_name = "libc.a(shr.o)"
+    else:
+        libc_name = "libc.a(shr_64.o)"
 else:
     libc_name = find_library("c")

@@ -38,11 +43,16 @@
         self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)

     def test_find(self):
+        # to track that at least one call to find_library() found something
+        found = False
         for name in ("c", "m"):
             lib = find_library(name)
             if lib:
+                found = True
                 cdll.LoadLibrary(lib)
                 CDLL(lib)
+        # test is FAILED if nothing was found
+        self.assertTrue(found)

     @unittest.skipUnless(os.name in ("nt", "ce"),
                          'test specific to Windows (NT/CE)')

Finally - there is the additional file: _aix.py - submitted as an attachment - and a patch with them all
History
Date User Action Args
2016-09-28 14:39:30Michael.Feltsetrecipients: + Michael.Felt, martin.panter, aixtools@gmail.com
2016-09-28 14:39:28Michael.Feltsetmessageid: <1475073568.44.0.800105651379.issue27435@psf.upfronthosting.co.za>
2016-09-28 14:39:28Michael.Feltlinkissue27435 messages
2016-09-28 14:39:28Michael.Feltcreate