1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Support for dynamic loading of extension modules */
33 /* If no dynamic linking is supported, this file still generates some code! */
37 #ifdef HAVE_SYS_PARAM_H
38 /* osdefs.h will define MAXPATHLEN if it's not already defined. */
39 #include <sys/param.h>
44 /* Explanation of some of the the various #defines used by dynamic linking...
46 symbol -- defined for:
48 DYNAMIC_LINK -- any kind of dynamic linking
49 USE_RLD -- NeXT dynamic linking with FVM shlibs
50 USE_DYLD -- NeXT dynamic linking with frameworks
51 USE_DL -- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
52 USE_SHLIB -- SunOS or IRIX 5 (SVR4?) shared libraries
53 _AIX -- AIX style dynamic linking
54 MS_WIN32 -- Windows NT style dynamic linking (using DLLs)
55 MS_WIN16 -- Windows 16-bit dynamic linking (using DLLs)
56 PYOS_OS2 -- IBM OS/2 dynamic linking (using DLLs)
57 _DL_FUNCPTR_DEFINED -- if the typedef dl_funcptr has been defined
58 USE_MAC_DYNAMIC_LOADING -- Mac CFM shared libraries
59 SHORT_EXT -- short extension for dynamic module, e.g. ".so"
60 LONG_EXT -- long extension, e.g. "module.so"
61 hpux -- HP-UX Dynamic Linking - defined by the compiler
62 __NetBSD__ -- NetBSD shared libraries
63 (assuming dlerror() was introduced between 1.2 and 1.3)
64 __FreeBSD__ -- FreeBSD shared libraries
65 __BEOS__ -- BeOS shared libraries - defined by the compiler
67 (The other WITH_* symbols are used only once, to set the
71 /* Configure dynamic linking */
82 typedef void (*dl_funcptr
)();
83 #define _DL_FUNCPTR_DEFINED 1
84 #define SHORT_EXT ".sl"
85 #define LONG_EXT "module.sl"
90 #define INCL_DOSERRORS
91 #define INCL_DOSMODULEMGR
93 typedef int (* APIENTRY dl_funcptr
)();
94 #define _DL_FUNCPTR_DEFINED 1
95 #define SHORT_EXT ".pyd"
96 #define LONG_EXT ".dll"
99 #if defined(__NetBSD__) && (NetBSD < 199712)
103 #define dlerror() "error in dynamic linking"
106 #ifdef MS_WINDOWS /* i.e. MS_WIN32 or MS_WIN16 */
110 typedef FARPROC dl_funcptr
;
111 #define _DL_FUNCPTR_DEFINED
113 #define SHORT_EXT "_d.pyd"
114 #define LONG_EXT "_d.dll"
116 #define SHORT_EXT ".pyd"
117 #define LONG_EXT ".dll"
124 #define SHORT_EXT ".so"
125 #define LONG_EXT "module.so"
126 #define FUNCNAME_PATTERN "_init%.200s"
129 #if defined(NeXT) && !defined(DYNAMIC_LINK)
132 /* Define this to 1 if you want be able to load ObjC modules as well:
133 it switches between two different way of loading modules on the NeXT,
134 one that directly interfaces with the dynamic loader (rld_load(), which
135 does not correctly load ObjC object files), and another that uses the
136 ObjC runtime (objc_loadModules()) to do the job.
137 You'll have to add ``-ObjC'' to the compiler flags if you set this to 1.
139 #define HANDLE_OBJC_MODULES 1
140 #if HANDLE_OBJC_MODULES
141 #include <objc/Object.h>
142 #include <objc/objc-load.h>
144 #define SHORT_EXT ".so"
145 #define LONG_EXT "module.so"
158 #ifdef USE_MAC_DYNAMIC_LOADING
160 #define SHORT_EXT ".slb"
162 #define LONG_EXT ".CFM68K.slb"
164 #define LONG_EXT ".ppc.slb"
166 #ifndef _DL_FUNCPTR_DEFINED
167 typedef void (*dl_funcptr
)();
171 #if !defined(DYNAMIC_LINK) && (defined(HAVE_DLOPEN) || defined(M_UNIX))
177 #undef USE_SHLIB /* AIX 4.2 and higher have dlfcn.h but we don't want it */
179 #define SHORT_EXT ".so"
180 #define LONG_EXT "module.so"
182 typedef void (*dl_funcptr
)();
183 #define _DL_FUNCPTR_DEFINED
184 static int aix_getoldmodules(void **);
185 static int aix_bindnewmodule(void *, void *);
186 static void aix_loaderror(char *);
190 #undef USE_SHLIB /* probably not defined anyway */
192 #define SHORT_EXT ".so"
193 #define LONG_EXT "module.so"
194 typedef void (*dl_funcptr
)(void);
195 #define _DL_FUNCPTR_DEFINED
197 #if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
201 #include <kernel/image.h>
202 #include <kernel/OS.h>
207 #include "pythread.h"
208 static PyThread_type_lock beos_dyn_lock
;
211 static PyObject
*beos_dyn_images
= NULL
;
213 static void beos_init_dyn( void );
214 static void beos_cleanup_dyn( void );
215 static void beos_nuke_dyn( PyObject
*item
);
216 static void beos_add_dyn( char *pathname
, image_id id
);
222 #include <sys/types.h>
223 #include <sys/stat.h>
224 #if defined(__NetBSD__) && (NetBSD < 199712)
232 #ifndef _DL_FUNCPTR_DEFINED
233 typedef void (*dl_funcptr
)();
238 #define SHORT_EXT ".so"
239 #define LONG_EXT "module.so"
240 #endif /* USE_SHLIB */
242 #if defined(USE_DL) || defined(hpux)
246 #ifdef USE_MAC_DYNAMIC_LOADING
248 #include <CodeFragments.h>
249 #ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
250 #define CFragConnectionID ConnectionID
251 #define kLoadCFrag 0x01
254 #include "TFileSpec.h" /* for Path2FSSpec() */
262 #include <mach-o/rld.h>
263 #ifndef _DL_FUNCPTR_DEFINED
264 typedef void (*dl_funcptr
)();
269 #include <mach-o/dyld.h>
270 #ifndef _DL_FUNCPTR_DEFINED
271 typedef void (*dl_funcptr
)();
273 #endif /* USE_DYLD */
275 extern char *Py_GetProgramName();
277 #ifndef FUNCNAME_PATTERN
278 #if defined(__hp9000s300) || (defined(__NetBSD__) || defined(__FreeBSD__)) && !defined(__ELF__) || defined(__OpenBSD__) || defined(__BORLANDC__) || defined(NeXT)
279 #define FUNCNAME_PATTERN "_init%.200s"
281 #define FUNCNAME_PATTERN "init%.200s"
285 #if !defined(SHORT_EXT) && !defined(LONG_EXT)
286 #define SHORT_EXT ".o"
287 #define LONG_EXT "module.o"
288 #endif /* !SHORT_EXT && !LONG_EXT */
290 #endif /* DYNAMIC_LINK */
292 struct filedescr _PyImport_Filetab
[] = {
294 {SHORT_EXT
, "rb", C_EXTENSION
},
295 #endif /* !SHORT_EXT */
297 {LONG_EXT
, "rb", C_EXTENSION
},
298 #endif /* !LONG_EXT */
299 {".py", "r", PY_SOURCE
},
300 {".pyc", "rb", PY_COMPILED
},
304 #ifdef NO_DYNAMIC_LINK
309 _PyImport_LoadDynamicModule(name
, pathname
, fp
)
315 PyErr_SetString(PyExc_ImportError
,
316 "dynamically linked modules not supported");
321 char *lastdot
, *shortname
, *packagecontext
;
329 static int nhandles
= 0;
331 if (strchr(pathname
, '/') == NULL
) {
332 /* Prefix bare filename with "./" */
333 sprintf(pathbuf
, "./%-.255s", pathname
);
337 if ((m
= _PyImport_FindExtension(name
, pathname
)) != NULL
) {
341 lastdot
= strrchr(name
, '.');
342 if (lastdot
== NULL
) {
343 packagecontext
= NULL
;
347 packagecontext
= name
;
348 shortname
= lastdot
+1;
350 sprintf(funcname
, FUNCNAME_PATTERN
, shortname
);
355 fstat(fileno(fp
), &statb
);
356 for (i
= 0; i
< nhandles
; i
++) {
357 if (statb
.st_dev
== handles
[i
].dev
&&
358 statb
.st_ino
== handles
[i
].ino
) {
359 p
= (dl_funcptr
) dlsym(handles
[i
].handle
,
364 if (nhandles
< 128) {
365 handles
[nhandles
].dev
= statb
.st_dev
;
366 handles
[nhandles
].ino
= statb
.st_ino
;
369 #endif /* USE_SHLIB */
370 #ifdef USE_MAC_DYNAMIC_LOADING
372 ** Dynamic loading of CFM shared libraries on the Mac. The
373 ** code has become more convoluted than it was, because we
374 ** want to be able to put multiple modules in a single
375 ** file. For this reason, we have to determine the fragment
376 ** name, and we cannot use the library entry point but we have
377 ** to locate the correct init routine "by hand".
381 CFragConnectionID connID
;
386 Boolean isfolder
, didsomething
;
391 CFragSymbolClass
class;
393 /* First resolve any aliases to find the real file */
395 err
= Path2FSSpec(pathname
, &libspec
);
397 (void)FSMakeFSSpec(0, 0, Pstring(pathname
), &libspec
);
398 err
= ResolveAliasFile(&libspec
, 1, &isfolder
, &didsomething
);
401 sprintf(buf
, "%.255s: %.200s",
402 pathname
, PyMac_StrError(err
));
403 PyErr_SetString(PyExc_ImportError
, buf
);
406 /* Next, determine the fragment name,
407 by stripping '.slb' and 'module' */
408 memcpy(fragname
+1, libspec
.name
+1, libspec
.name
[0]);
409 fragname
[0] = libspec
.name
[0];
410 if( strncmp((char *)(fragname
+1+fragname
[0]-4),
413 if ( strncmp((char *)(fragname
+1+fragname
[0]-6),
417 (or return the connID if it is already loaded */
418 err
= GetDiskFragment(&libspec
, 0, 0, fragname
,
419 kLoadCFrag
, &connID
, &mainAddr
,
422 sprintf(buf
, "%.*s: %.200s",
423 errMessage
[0], errMessage
+1,
424 PyMac_StrError(err
));
425 PyErr_SetString(PyExc_ImportError
, buf
);
428 /* Locate the address of the correct init function */
429 err
= FindSymbol(connID
, Pstring(funcname
), &symAddr
, &class);
431 sprintf(buf
, "%s: %.200s",
432 funcname
, PyMac_StrError(err
));
433 PyErr_SetString(PyExc_ImportError
, buf
);
436 p
= (dl_funcptr
)symAddr
;
438 #endif /* USE_MAC_DYNAMIC_LOADING */
442 /* RTLD_NOW: resolve externals now
443 (i.e. core dump now if some are missing) */
444 void *handle
= dlopen(pathname
, RTLD_NOW
);
448 printf("dlopen(\"%s\", %d);\n", pathname
,
450 handle
= dlopen(pathname
, RTLD_LAZY
);
451 #endif /* RTLD_NOW */
452 if (handle
== NULL
) {
453 PyErr_SetString(PyExc_ImportError
, dlerror());
456 if (fp
!= NULL
&& nhandles
< 128)
457 handles
[nhandles
++].handle
= handle
;
458 p
= (dl_funcptr
) dlsym(handle
, funcname
);
460 #endif /* USE_SHLIB */
463 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
464 -- of the shared module unresolved. Thus we have to resolve them
465 -- explicitely with loadbind. The new module is loaded, then we
466 -- resolve its symbols using the list of already loaded modules
467 -- (only those that belong to the python executable). Get these
468 -- with loadquery(L_GETINFO).
471 static void *staticmodlistptr
= NULL
;
473 if (!staticmodlistptr
)
474 if (aix_getoldmodules(&staticmodlistptr
) == -1)
476 p
= (dl_funcptr
) load(pathname
, L_NOAUTODEFER
, 0);
478 aix_loaderror(pathname
);
481 if (aix_bindnewmodule((void *)p
, staticmodlistptr
) == -1) {
482 aix_loaderror(pathname
);
491 if (strchr(pathname
, SEP
) == NULL
&&
492 strchr(pathname
, ALTSEP
) == NULL
)
494 /* Prefix bare filename with ".\" */
497 _getcwd(pathbuf
, sizeof pathbuf
);
498 if (*p
!= '\0' && p
[1] == ':')
500 sprintf(p
, ".\\%-.255s", pathname
);
503 /* Look for dependent DLLs in directory of pathname first */
504 /* XXX This call doesn't exist in Windows CE */
505 hDLL
= LoadLibraryEx(pathname
, NULL
,
506 LOAD_WITH_ALTERED_SEARCH_PATH
);
509 unsigned int errorCode
;
511 /* Get an error string from Win32 error code */
512 char theInfo
[256]; /* Pointer to error text
514 int theLength
; /* Length of error text */
516 errorCode
= GetLastError();
518 theLength
= FormatMessage(
519 FORMAT_MESSAGE_FROM_SYSTEM
, /* flags */
520 NULL
, /* message source */
521 errorCode
, /* the message (error) ID */
522 0, /* default language environment */
523 (LPTSTR
) theInfo
, /* the buffer */
524 sizeof(theInfo
), /* the buffer size */
525 NULL
); /* no additional format args. */
527 /* Problem: could not get the error message.
528 This should not happen if called correctly. */
529 if (theLength
== 0) {
531 "DLL load failed with error code %d",
535 /* For some reason a \r\n
536 is appended to the text */
537 if (theLength
>= 2 &&
538 theInfo
[theLength
-2] == '\r' &&
539 theInfo
[theLength
-1] == '\n') {
541 theInfo
[theLength
] = '\0';
543 strcpy(errBuf
, "DLL load failed: ");
544 len
= strlen(errBuf
);
545 strncpy(errBuf
+len
, theInfo
,
547 errBuf
[sizeof(errBuf
)-1] = '\0';
549 PyErr_SetString(PyExc_ImportError
, errBuf
);
552 p
= GetProcAddress(hDLL
, funcname
);
554 #endif /* MS_WIN32 */
559 if (strchr(pathname
, SEP
) == NULL
&&
560 strchr(pathname
, ALTSEP
) == NULL
)
562 /* Prefix bare filename with ".\" */
563 sprintf(pathbuf
, ".\\%-.13s", pathname
);
566 hDLL
= LoadLibrary(pathname
);
567 if (hDLL
< HINSTANCE_ERROR
){
570 "DLL load failed with error code %d", hDLL
);
571 PyErr_SetString(PyExc_ImportError
, errBuf
);
574 p
= GetProcAddress(hDLL
, funcname
);
576 #endif /* MS_WIN16 */
578 #if defined(PYOS_OS2)
582 char failreason
[256];
584 rc
= DosLoadModule(failreason
,
589 if (rc
!= NO_ERROR
) {
592 "DLL load failed, rc = %d, problem '%s': %s",
594 PyErr_SetString(PyExc_ImportError
, errBuf
);
598 rc
= DosQueryProcAddr(hDLL
, 0L, funcname
, &p
);
600 p
= NULL
; /* Signify Failure to Acquire Entrypoint */
602 #endif /* PYOS_OS2 */
605 p
= dl_loadmod(Py_GetProgramName(), pathname
, funcname
);
609 NXStream
*errorStream
;
610 struct mach_header
*new_header
;
611 const char *filenames
[2];
615 errorStream
= NXOpenMemory(NULL
, 0, NX_WRITEONLY
);
616 filenames
[0] = pathname
;
619 #if HANDLE_OBJC_MODULES
621 /* The following very bogus line of code ensures that
622 objc_msgSend, etc are linked into the binary. Without
623 it, dynamic loading of a module that includes objective-c
624 method calls will fail with "undefined symbol _objc_msgSend()".
625 This remains true even in the presence of the -ObjC flag
631 /* objc_loadModules() dynamically loads the object files
632 indicated by the paths in filenames. If there are any
633 errors generated during loading -- typically due to the
634 inability to find particular symbols -- an error message
635 will be written to errorStream.
636 It returns 0 if the module is successfully loaded, 1
640 ret
= !objc_loadModules(filenames
, errorStream
,
641 NULL
, &new_header
, NULL
);
643 #else /* !HANDLE_OBJC_MODULES */
645 ret
= rld_load(errorStream
, &new_header
,
648 #endif /* HANDLE_OBJC_MODULES */
650 /* extract the error messages for the exception */
655 NXPutc(errorStream
, (char)0);
657 NXGetMemoryBuffer(errorStream
,
658 &streamBuf
, &len
, &maxLen
);
659 PyErr_SetString(PyExc_ImportError
, streamBuf
);
662 if(ret
&& rld_lookup(errorStream
, funcname
, &ptr
))
663 p
= (dl_funcptr
) ptr
;
665 NXCloseMemory(errorStream
, NX_FREEBUFFER
);
672 /* This is also NeXT-specific. However, frameworks (the new style
673 of shared library) and rld() can't be used in the same program;
674 instead, you have to use dyld, which is mostly unimplemented. */
676 NSObjectFileImageReturnCode rc
;
677 NSObjectFileImage image
;
681 const char *errString
;
683 rc
= NSCreateObjectFileImageFromFile(pathname
, &image
);
686 case NSObjectFileImageFailure
:
687 NSObjectFileImageFormat
:
688 /* for these a message is printed on stderr by dyld */
689 errString
= "Can't create object file image";
691 case NSObjectFileImageSuccess
:
694 case NSObjectFileImageInappropriateFile
:
695 errString
= "Inappropriate file type for dynamic loading";
697 case NSObjectFileImageArch
:
698 errString
= "Wrong CPU type in object file";
700 NSObjectFileImageAccess
:
701 errString
= "Can't read object file (no access)";
704 if (errString
== NULL
) {
705 newModule
= NSLinkModule(image
, pathname
, TRUE
);
707 errString
= "Failure linking new module";
709 if (errString
!= NULL
) {
710 PyErr_SetString(PyExc_ImportError
, errString
);
713 if (!NSIsSymbolNameDefined(funcname
)) {
714 /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */
715 NSUnLinkModule(newModule
, FALSE
);
716 PyErr_Format(PyExc_ImportError
, "Loaded module does not contain symbol %s", funcname
);
719 theSym
= NSLookupAndBindSymbol(funcname
);
720 p
= (dl_funcptr
)NSAddressOfSymbol(theSym
);
722 #endif /* USE_DYLD */
728 flags
= BIND_FIRST
| BIND_DEFERRED
;
729 if (Py_VerboseFlag
) {
730 flags
= DYNAMIC_PATH
| BIND_FIRST
| BIND_IMMEDIATE
|
731 BIND_NONFATAL
| BIND_VERBOSE
;
732 printf("shl_load %s\n",pathname
);
734 lib
= shl_load(pathname
, flags
, 0);
735 /* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
740 sprintf(buf
, "Failed to load %.200s", pathname
);
741 PyErr_SetString(PyExc_ImportError
, buf
);
745 printf("shl_findsym %s\n", funcname
);
746 shl_findsym(&lib
, funcname
, TYPE_UNDEFINED
, (void *) &p
);
747 if (p
== NULL
&& Py_VerboseFlag
)
755 char fullpath
[PATH_MAX
];
757 if( Py_VerboseFlag
) {
758 printf( "load_add_on( %s )\n", pathname
);
761 /* Hmm, this old bug appears to have regenerated itself; if the
762 * path isn't absolute, load_add_on() will fail. Reported to Be
765 if( pathname
[0] != '/' ) {
766 (void)getcwd( fullpath
, PATH_MAX
);
767 (void)strncat( fullpath
, "/", PATH_MAX
);
768 (void)strncat( fullpath
, pathname
, PATH_MAX
);
770 if( Py_VerboseFlag
) {
771 printf( "load_add_on( %s )\n", fullpath
);
774 (void)strcpy( fullpath
, pathname
);
777 the_id
= load_add_on( fullpath
);
778 if( the_id
< B_NO_ERROR
) {
779 /* It's too bad load_add_on() doesn't set errno or something...
781 char buff
[256]; /* hate hard-coded string sizes... */
783 if( Py_VerboseFlag
) {
784 printf( "load_add_on( %s ) failed", fullpath
);
789 sprintf( buff
, "BeOS: Failed to load %.200s", fullpath
);
792 sprintf( buff
, "Unknown error loading %.200s", fullpath
);
796 PyErr_SetString( PyExc_ImportError
, buff
);
800 if( Py_VerboseFlag
) {
801 printf( "get_image_symbol( %s )\n", funcname
);
804 retval
= get_image_symbol( the_id
, funcname
, B_SYMBOL_TYPE_TEXT
, &p
);
805 if( retval
!= B_NO_ERROR
|| p
== NULL
) {
806 /* That's bad, we can't find that symbol in the module...
808 char buff
[256]; /* hate hard-coded string sizes... */
810 if( Py_VerboseFlag
) {
811 printf( "get_image_symbol( %s ) failed", funcname
);
816 sprintf( buff
, "can't load init function for dynamic module: "
817 "Invalid image ID for %.180s", fullpath
);
820 sprintf( buff
, "can't load init function for dynamic module: "
821 "Bad index for %.180s", funcname
);
824 sprintf( buff
, "can't load init function for dynamic module: "
825 "Unknown error looking up %.180s", funcname
);
829 retval
= unload_add_on( the_id
);
831 PyErr_SetString( PyExc_ImportError
, buff
);
835 /* Save the module name and image ID for later so we can clean up
838 beos_add_dyn( name
, the_id
);
840 #endif /* __BEOS__ */
845 PyErr_Format(PyExc_ImportError
,
846 "dynamic module does not define init function (%.200s)",
850 _Py_PackageContext
= packagecontext
;
852 _Py_PackageContext
= NULL
;
853 if (PyErr_Occurred())
855 if (_PyImport_FixupExtension(name
, pathname
) == NULL
)
858 m
= PyDict_GetItemString(PyImport_GetModuleDict(), name
);
860 PyErr_SetString(PyExc_SystemError
,
861 "dynamic module not initialized properly");
864 /* Remember the filename as the __file__ attribute */
865 d
= PyModule_GetDict(m
);
866 s
= PyString_FromString(pathname
);
867 if (s
== NULL
|| PyDict_SetItemString(d
, "__file__", s
) != 0)
868 PyErr_Clear(); /* Not important enough to report */
872 "import %s # dynamically loaded from %s\n",
876 #endif /* DYNAMIC_LINK */
882 #include <ctype.h> /* for isdigit() */
883 #include <errno.h> /* for global errno */
884 #include <string.h> /* for strerror() */
885 #include <stdlib.h> /* for malloc(), free() */
887 typedef struct Module
{
890 } Module
, *ModulePtr
;
893 aix_getoldmodules(modlistptr
)
896 register ModulePtr modptr
, prevmodptr
;
897 register struct ld_info
*ldiptr
;
898 register char *ldibuf
;
899 register int errflag
, bufsize
= 1024;
900 register unsigned int offset
;
903 -- Get the list of loaded modules into ld_info structures.
905 if ((ldibuf
= malloc(bufsize
)) == NULL
) {
906 PyErr_SetString(PyExc_ImportError
, strerror(errno
));
909 while ((errflag
= loadquery(L_GETINFO
, ldibuf
, bufsize
)) == -1
910 && errno
== ENOMEM
) {
913 if ((ldibuf
= malloc(bufsize
)) == NULL
) {
914 PyErr_SetString(PyExc_ImportError
, strerror(errno
));
919 PyErr_SetString(PyExc_ImportError
, strerror(errno
));
923 -- Make the modules list from the ld_info structures.
925 ldiptr
= (struct ld_info
*)ldibuf
;
928 if (strstr(ldiptr
->ldinfo_filename
, "python") == NULL
) {
930 -- Extract only the modules containing "python" as a
931 -- substring, like the "python[version]" executable or
932 -- "libpython[version].a" in case python is embedded.
934 offset
= (unsigned int)ldiptr
->ldinfo_next
;
935 ldiptr
= (struct ld_info
*)((unsigned int)
939 if ((modptr
= (ModulePtr
)malloc(sizeof(Module
))) == NULL
) {
940 PyErr_SetString(PyExc_ImportError
, strerror(errno
));
941 while (*modlistptr
) {
942 modptr
= (ModulePtr
)*modlistptr
;
943 *modlistptr
= (void *)modptr
->next
;
948 modptr
->entry
= ldiptr
->ldinfo_dataorg
;
950 if (prevmodptr
== NULL
)
951 *modlistptr
= (void *)modptr
;
953 prevmodptr
->next
= modptr
;
955 offset
= (unsigned int)ldiptr
->ldinfo_next
;
956 ldiptr
= (struct ld_info
*)((unsigned int)ldiptr
+ offset
);
963 aix_bindnewmodule(newmoduleptr
, modlistptr
)
967 register ModulePtr modptr
;
970 -- Bind the new module with the list of loaded modules.
972 for (modptr
= (ModulePtr
)modlistptr
; modptr
; modptr
= modptr
->next
)
973 if (loadbind(0, modptr
->entry
, newmoduleptr
) != 0)
979 aix_loaderror(pathname
)
983 char *message
[1024], errbuf
[1024];
990 {L_ERROR_TOOMANY
, "too many errors, rest skipped."},
991 {L_ERROR_NOLIB
, "can't load library:"},
992 {L_ERROR_UNDEF
, "can't find symbol in library:"},
994 "RLD index out of range or bad relocation type:"},
995 {L_ERROR_FORMAT
, "not a valid, executable xcoff file:"},
997 "file not an archive or does not contain requested member:"},
998 {L_ERROR_TYPE
, "symbol table mismatch:"},
999 {L_ERROR_ALIGN
, "text alignment in file is wrong."},
1000 {L_ERROR_SYSTEM
, "System error:"},
1001 {L_ERROR_ERRNO
, NULL
}
1004 #define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
1005 #define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
1007 sprintf(errbuf
, "from module %.200s ", pathname
);
1009 if (!loadquery(L_GETMESSAGES
, &message
[0], sizeof(message
))) {
1010 ERRBUF_APPEND(strerror(errno
));
1011 ERRBUF_APPEND("\n");
1013 for(i
= 0; message
[i
] && *message
[i
]; i
++) {
1014 int nerr
= atoi(message
[i
]);
1015 for (j
=0; j
<LOAD_ERRTAB_LEN
; j
++) {
1016 if (nerr
== load_errtab
[j
].errNo
&& load_errtab
[j
].errstr
)
1017 ERRBUF_APPEND(load_errtab
[j
].errstr
);
1019 while (isdigit(*message
[i
])) message
[i
]++ ;
1020 ERRBUF_APPEND(message
[i
]);
1021 ERRBUF_APPEND("\n");
1023 errbuf
[strlen(errbuf
)-1] = '\0'; /* trim off last newline */
1024 PyErr_SetString(PyExc_ImportError
, errbuf
);
1031 /* ----------------------------------------------------------------------
1032 * BeOS dynamic loading support
1034 * This uses shared libraries, but BeOS has its own way of doing things
1035 * (much easier than dlfnc.h, from the look of things). We'll use a
1036 * Python Dictionary object to store the images_ids so we can be very
1037 * nice and unload them when we exit.
1039 * Note that this is thread-safe. Probably irrelevent, because of losing
1040 * systems... Python probably disables threads while loading modules.
1041 * Note the use of "probably"! Better to be safe than sorry. [chrish]
1043 * As of 1.5.1 this should also work properly when you've configured
1044 * Python without thread support; the 1.5 version required it, which wasn't
1045 * very friendly. Note that I haven't tested it without threading... why
1046 * would you want to avoid threads on BeOS? [chrish]
1048 * As of 1.5.2, the PyImport_BeImageID() function has been removed; Donn
1049 * tells me it's not necessary anymore because of PyCObject_Import().
1054 * Initialize our dictionary, and the dictionary mutex.
1056 static void beos_init_dyn( void )
1058 /* We're protected from a race condition here by the atomic init_count
1061 static int32 init_count
= 0;
1064 val
= atomic_add( &init_count
, 1 );
1065 if( beos_dyn_images
== NULL
&& val
== 0 ) {
1066 beos_dyn_images
= PyDict_New();
1068 beos_dyn_lock
= PyThread_allocate_lock();
1070 atexit( beos_cleanup_dyn
);
1074 /* atexit() handler that'll call unload_add_on() for every item in the
1077 static void beos_cleanup_dyn( void )
1079 if( beos_dyn_images
) {
1085 PyThread_acquire_lock( beos_dyn_lock
, 1 );
1088 id_list
= PyDict_Values( beos_dyn_images
);
1090 list_size
= PyList_Size( id_list
);
1091 for( idx
= 0; idx
< list_size
; idx
++ ) {
1094 the_item
= PyList_GetItem( id_list
, idx
);
1095 beos_nuke_dyn( the_item
);
1098 PyDict_Clear( beos_dyn_images
);
1101 PyThread_free_lock( beos_dyn_lock
);
1106 /* Whack an item; the item is an image_id in disguise, so we'll call
1107 * unload_add_on() for it.
1109 static void beos_nuke_dyn( PyObject
*item
)
1114 image_id id
= (image_id
)PyInt_AsLong( item
);
1116 retval
= unload_add_on( id
);
1121 * Add an image_id to the dictionary; the module name of the loaded image
1122 * is the key. Note that if the key is already in the dict, we unload
1123 * that image; this should allow reload() to work on dynamically loaded
1124 * modules (super-keen!).
1126 static void beos_add_dyn( char *name
, image_id id
)
1131 if( beos_dyn_images
== NULL
) {
1136 retval
= PyThread_acquire_lock( beos_dyn_lock
, 1 );
1139 /* If there's already an object with this key in the dictionary,
1140 * we're doing a reload(), so let's nuke it.
1142 py_id
= PyDict_GetItemString( beos_dyn_images
, name
);
1144 beos_nuke_dyn( py_id
);
1145 retval
= PyDict_DelItemString( beos_dyn_images
, name
);
1148 py_id
= PyInt_FromLong( (long)id
);
1150 retval
= PyDict_SetItemString( beos_dyn_images
, name
, py_id
);
1154 PyThread_release_lock( beos_dyn_lock
);
1158 #endif /* __BEOS__ */