Class around PixMap objects that allows more python-like access. By Joe Strout.
[python/dscho.git] / Python / importdl.c
blob3b43bbc0a213f6805052697de5ce55364bc91f7b
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
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
15 permission.
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! */
35 #include "Python.h"
37 #ifdef HAVE_SYS_PARAM_H
38 /* osdefs.h will define MAXPATHLEN if it's not already defined. */
39 #include <sys/param.h>
40 #endif
41 #include "osdefs.h"
42 #include "importdl.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
68 appropriate symbols.)
71 /* Configure dynamic linking */
73 #ifdef __hpux
74 #ifndef hpux
75 #define hpux
76 #endif
77 #endif
79 #ifdef hpux
80 #define DYNAMIC_LINK
81 #include <errno.h>
82 typedef void (*dl_funcptr)();
83 #define _DL_FUNCPTR_DEFINED 1
84 #define SHORT_EXT ".sl"
85 #define LONG_EXT "module.sl"
86 #endif
88 #if defined(PYOS_OS2)
89 #define DYNAMIC_LINK
90 #define INCL_DOSERRORS
91 #define INCL_DOSMODULEMGR
92 #include <os2.h>
93 typedef int (* APIENTRY dl_funcptr)();
94 #define _DL_FUNCPTR_DEFINED 1
95 #define SHORT_EXT ".pyd"
96 #define LONG_EXT ".dll"
97 #endif
99 #if defined(__NetBSD__) && (NetBSD < 199712)
100 #define DYNAMIC_LINK
101 #define USE_SHLIB
103 #define dlerror() "error in dynamic linking"
104 #endif
106 #ifdef MS_WINDOWS /* i.e. MS_WIN32 or MS_WIN16 */
107 #define DYNAMIC_LINK
108 #include <windows.h>
109 #include <direct.h>
110 typedef FARPROC dl_funcptr;
111 #define _DL_FUNCPTR_DEFINED
112 #ifdef _DEBUG
113 #define SHORT_EXT "_d.pyd"
114 #define LONG_EXT "_d.dll"
115 #else
116 #define SHORT_EXT ".pyd"
117 #define LONG_EXT ".dll"
118 #endif
119 #endif
121 #ifdef WITH_DYLD
122 #define DYNAMIC_LINK
123 #define USE_DYLD
124 #define SHORT_EXT ".so"
125 #define LONG_EXT "module.so"
126 #define FUNCNAME_PATTERN "_init%.200s"
127 #endif
129 #if defined(NeXT) && !defined(DYNAMIC_LINK)
130 #define DYNAMIC_LINK
131 #define USE_RLD
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>
143 #endif
144 #define SHORT_EXT ".so"
145 #define LONG_EXT "module.so"
146 #endif
148 #ifdef WITH_SGI_DL
149 #define DYNAMIC_LINK
150 #define USE_DL
151 #endif
153 #ifdef WITH_DL_DLD
154 #define DYNAMIC_LINK
155 #define USE_DL
156 #endif
158 #ifdef USE_MAC_DYNAMIC_LOADING
159 #define DYNAMIC_LINK
160 #define SHORT_EXT ".slb"
161 #ifdef __CFM68K__
162 #define LONG_EXT ".CFM68K.slb"
163 #else
164 #define LONG_EXT ".ppc.slb"
165 #endif
166 #ifndef _DL_FUNCPTR_DEFINED
167 typedef void (*dl_funcptr)();
168 #endif
169 #endif
171 #if !defined(DYNAMIC_LINK) && (defined(HAVE_DLOPEN) || defined(M_UNIX))
172 #define DYNAMIC_LINK
173 #define USE_SHLIB
174 #endif
176 #ifdef _AIX
177 #undef USE_SHLIB /* AIX 4.2 and higher have dlfcn.h but we don't want it */
178 #define DYNAMIC_LINK
179 #define SHORT_EXT ".so"
180 #define LONG_EXT "module.so"
181 #include <sys/ldr.h>
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 *);
187 #endif
189 #ifdef __BEOS__
190 #undef USE_SHLIB /* probably not defined anyway */
191 #define DYNAMIC_LINK
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)
198 #undef MAXPATHLEN
199 #endif
201 #include <kernel/image.h>
202 #include <kernel/OS.h>
203 #include <stdlib.h>
204 #include <unistd.h>
206 #ifdef WITH_THREAD
207 #include "pythread.h"
208 static PyThread_type_lock beos_dyn_lock;
209 #endif
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 );
217 #endif
219 #ifdef DYNAMIC_LINK
221 #ifdef USE_SHLIB
222 #include <sys/types.h>
223 #include <sys/stat.h>
224 #if defined(__NetBSD__) && (NetBSD < 199712)
225 #include <nlist.h>
226 #include <link.h>
227 #else
228 #ifdef HAVE_DLFCN_H
229 #include <dlfcn.h>
230 #endif
231 #endif
232 #ifndef _DL_FUNCPTR_DEFINED
233 typedef void (*dl_funcptr)();
234 #endif
235 #ifndef RTLD_LAZY
236 #define RTLD_LAZY 1
237 #endif
238 #define SHORT_EXT ".so"
239 #define LONG_EXT "module.so"
240 #endif /* USE_SHLIB */
242 #if defined(USE_DL) || defined(hpux)
243 #include "dl.h"
244 #endif
246 #ifdef USE_MAC_DYNAMIC_LOADING
247 #include <Aliases.h>
248 #include <CodeFragments.h>
249 #ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
250 #define CFragConnectionID ConnectionID
251 #define kLoadCFrag 0x01
252 #endif
253 #ifdef USE_GUSI
254 #include "TFileSpec.h" /* for Path2FSSpec() */
255 #endif
256 #include <Files.h>
257 #include "macdefs.h"
258 #include "macglue.h"
259 #endif
261 #ifdef USE_RLD
262 #include <mach-o/rld.h>
263 #ifndef _DL_FUNCPTR_DEFINED
264 typedef void (*dl_funcptr)();
265 #endif
266 #endif /* USE_RLD */
268 #ifdef USE_DYLD
269 #include <mach-o/dyld.h>
270 #ifndef _DL_FUNCPTR_DEFINED
271 typedef void (*dl_funcptr)();
272 #endif
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"
280 #else
281 #define FUNCNAME_PATTERN "init%.200s"
282 #endif
283 #endif
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[] = {
293 #ifdef SHORT_EXT
294 {SHORT_EXT, "rb", C_EXTENSION},
295 #endif /* !SHORT_EXT */
296 #ifdef LONG_EXT
297 {LONG_EXT, "rb", C_EXTENSION},
298 #endif /* !LONG_EXT */
299 {".py", "r", PY_SOURCE},
300 {".pyc", "rb", PY_COMPILED},
301 {0, 0}
304 #ifdef NO_DYNAMIC_LINK
305 #undef DYNAMIC_LINK
306 #endif
308 PyObject *
309 _PyImport_LoadDynamicModule(name, pathname, fp)
310 char *name;
311 char *pathname;
312 FILE *fp;
314 #ifndef DYNAMIC_LINK
315 PyErr_SetString(PyExc_ImportError,
316 "dynamically linked modules not supported");
317 return NULL;
318 #else
319 PyObject *m, *d, *s;
320 char funcname[258];
321 char *lastdot, *shortname, *packagecontext;
322 dl_funcptr p = NULL;
323 #ifdef USE_SHLIB
324 static struct {
325 dev_t dev;
326 ino_t ino;
327 void *handle;
328 } handles[128];
329 static int nhandles = 0;
330 char pathbuf[260];
331 if (strchr(pathname, '/') == NULL) {
332 /* Prefix bare filename with "./" */
333 sprintf(pathbuf, "./%-.255s", pathname);
334 pathname = pathbuf;
336 #endif
337 if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
338 Py_INCREF(m);
339 return m;
341 lastdot = strrchr(name, '.');
342 if (lastdot == NULL) {
343 packagecontext = NULL;
344 shortname = name;
346 else {
347 packagecontext = name;
348 shortname = lastdot+1;
350 sprintf(funcname, FUNCNAME_PATTERN, shortname);
351 #ifdef USE_SHLIB
352 if (fp != NULL) {
353 int i;
354 struct stat statb;
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,
360 funcname);
361 goto got_it;
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".
380 FSSpec libspec;
381 CFragConnectionID connID;
382 Ptr mainAddr;
383 Str255 errMessage;
384 OSErr err;
385 #ifndef USE_GUSI
386 Boolean isfolder, didsomething;
387 #endif
388 char buf[512];
389 Str63 fragname;
390 Ptr symAddr;
391 CFragSymbolClass class;
393 /* First resolve any aliases to find the real file */
394 #ifdef USE_GUSI
395 err = Path2FSSpec(pathname, &libspec);
396 #else
397 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
398 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
399 #endif
400 if ( err ) {
401 sprintf(buf, "%.255s: %.200s",
402 pathname, PyMac_StrError(err));
403 PyErr_SetString(PyExc_ImportError, buf);
404 return NULL;
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),
411 ".slb", 4) == 0 )
412 fragname[0] -= 4;
413 if ( strncmp((char *)(fragname+1+fragname[0]-6),
414 "module", 6) == 0 )
415 fragname[0] -= 6;
416 /* Load the fragment
417 (or return the connID if it is already loaded */
418 err = GetDiskFragment(&libspec, 0, 0, fragname,
419 kLoadCFrag, &connID, &mainAddr,
420 errMessage);
421 if ( err ) {
422 sprintf(buf, "%.*s: %.200s",
423 errMessage[0], errMessage+1,
424 PyMac_StrError(err));
425 PyErr_SetString(PyExc_ImportError, buf);
426 return NULL;
428 /* Locate the address of the correct init function */
429 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
430 if ( err ) {
431 sprintf(buf, "%s: %.200s",
432 funcname, PyMac_StrError(err));
433 PyErr_SetString(PyExc_ImportError, buf);
434 return NULL;
436 p = (dl_funcptr)symAddr;
438 #endif /* USE_MAC_DYNAMIC_LOADING */
439 #ifdef USE_SHLIB
441 #ifdef RTLD_NOW
442 /* RTLD_NOW: resolve externals now
443 (i.e. core dump now if some are missing) */
444 void *handle = dlopen(pathname, RTLD_NOW);
445 #else
446 void *handle;
447 if (Py_VerboseFlag)
448 printf("dlopen(\"%s\", %d);\n", pathname,
449 RTLD_LAZY);
450 handle = dlopen(pathname, RTLD_LAZY);
451 #endif /* RTLD_NOW */
452 if (handle == NULL) {
453 PyErr_SetString(PyExc_ImportError, dlerror());
454 return NULL;
456 if (fp != NULL && nhandles < 128)
457 handles[nhandles++].handle = handle;
458 p = (dl_funcptr) dlsym(handle, funcname);
460 #endif /* USE_SHLIB */
461 #ifdef _AIX
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)
475 return NULL;
476 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
477 if (p == NULL) {
478 aix_loaderror(pathname);
479 return NULL;
481 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
482 aix_loaderror(pathname);
483 return NULL;
486 #endif /* _AIX */
487 #ifdef MS_WIN32
489 HINSTANCE hDLL;
490 char pathbuf[260];
491 if (strchr(pathname, SEP) == NULL &&
492 strchr(pathname, ALTSEP) == NULL)
494 /* Prefix bare filename with ".\" */
495 char *p = pathbuf;
496 *p = '\0';
497 _getcwd(pathbuf, sizeof pathbuf);
498 if (*p != '\0' && p[1] == ':')
499 p += 2;
500 sprintf(p, ".\\%-.255s", pathname);
501 pathname = pathbuf;
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);
507 if (hDLL==NULL){
508 char errBuf[256];
509 unsigned int errorCode;
511 /* Get an error string from Win32 error code */
512 char theInfo[256]; /* Pointer to error text
513 from system */
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) {
530 sprintf(errBuf,
531 "DLL load failed with error code %d",
532 errorCode);
533 } else {
534 int len;
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') {
540 theLength -= 2;
541 theInfo[theLength] = '\0';
543 strcpy(errBuf, "DLL load failed: ");
544 len = strlen(errBuf);
545 strncpy(errBuf+len, theInfo,
546 sizeof(errBuf)-len);
547 errBuf[sizeof(errBuf)-1] = '\0';
549 PyErr_SetString(PyExc_ImportError, errBuf);
550 return NULL;
552 p = GetProcAddress(hDLL, funcname);
554 #endif /* MS_WIN32 */
555 #ifdef MS_WIN16
557 HINSTANCE hDLL;
558 char pathbuf[16];
559 if (strchr(pathname, SEP) == NULL &&
560 strchr(pathname, ALTSEP) == NULL)
562 /* Prefix bare filename with ".\" */
563 sprintf(pathbuf, ".\\%-.13s", pathname);
564 pathname = pathbuf;
566 hDLL = LoadLibrary(pathname);
567 if (hDLL < HINSTANCE_ERROR){
568 char errBuf[256];
569 sprintf(errBuf,
570 "DLL load failed with error code %d", hDLL);
571 PyErr_SetString(PyExc_ImportError, errBuf);
572 return NULL;
574 p = GetProcAddress(hDLL, funcname);
576 #endif /* MS_WIN16 */
578 #if defined(PYOS_OS2)
580 APIRET rc;
581 HMODULE hDLL;
582 char failreason[256];
584 rc = DosLoadModule(failreason,
585 sizeof(failreason),
586 pathname,
587 &hDLL);
589 if (rc != NO_ERROR) {
590 char errBuf[256];
591 sprintf(errBuf,
592 "DLL load failed, rc = %d, problem '%s': %s",
593 rc, failreason);
594 PyErr_SetString(PyExc_ImportError, errBuf);
595 return NULL;
598 rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
599 if (rc != NO_ERROR)
600 p = NULL; /* Signify Failure to Acquire Entrypoint */
602 #endif /* PYOS_OS2 */
604 #ifdef USE_DL
605 p = dl_loadmod(Py_GetProgramName(), pathname, funcname);
606 #endif /* USE_DL */
607 #ifdef USE_RLD
609 NXStream *errorStream;
610 struct mach_header *new_header;
611 const char *filenames[2];
612 long ret;
613 unsigned long ptr;
615 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
616 filenames[0] = pathname;
617 filenames[1] = NULL;
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
626 to the compiler
629 [Object name];
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
637 otherwise.
640 ret = !objc_loadModules(filenames, errorStream,
641 NULL, &new_header, NULL);
643 #else /* !HANDLE_OBJC_MODULES */
645 ret = rld_load(errorStream, &new_header,
646 filenames, NULL);
648 #endif /* HANDLE_OBJC_MODULES */
650 /* extract the error messages for the exception */
651 if(!ret) {
652 char *streamBuf;
653 int len, maxLen;
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);
667 if(!ret)
668 return NULL;
670 #endif /* USE_RLD */
671 #ifdef USE_DYLD
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;
678 NSModule newModule;
679 NSSymbol theSym;
680 void *symaddr;
681 const char *errString;
683 rc = NSCreateObjectFileImageFromFile(pathname, &image);
684 switch(rc) {
685 default:
686 case NSObjectFileImageFailure:
687 NSObjectFileImageFormat:
688 /* for these a message is printed on stderr by dyld */
689 errString = "Can't create object file image";
690 break;
691 case NSObjectFileImageSuccess:
692 errString = NULL;
693 break;
694 case NSObjectFileImageInappropriateFile:
695 errString = "Inappropriate file type for dynamic loading";
696 break;
697 case NSObjectFileImageArch:
698 errString = "Wrong CPU type in object file";
699 break;
700 NSObjectFileImageAccess:
701 errString = "Can't read object file (no access)";
702 break;
704 if (errString == NULL) {
705 newModule = NSLinkModule(image, pathname, TRUE);
706 if (!newModule)
707 errString = "Failure linking new module";
709 if (errString != NULL) {
710 PyErr_SetString(PyExc_ImportError, errString);
711 return NULL;
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);
717 return NULL;
719 theSym = NSLookupAndBindSymbol(funcname);
720 p = (dl_funcptr)NSAddressOfSymbol(theSym);
722 #endif /* USE_DYLD */
723 #ifdef hpux
725 shl_t lib;
726 int flags;
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? */
736 if (lib == NULL) {
737 char buf[256];
738 if (Py_VerboseFlag)
739 perror(pathname);
740 sprintf(buf, "Failed to load %.200s", pathname);
741 PyErr_SetString(PyExc_ImportError, buf);
742 return NULL;
744 if (Py_VerboseFlag)
745 printf("shl_findsym %s\n", funcname);
746 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
747 if (p == NULL && Py_VerboseFlag)
748 perror(funcname);
750 #endif /* hpux */
751 #ifdef __BEOS__
753 image_id the_id;
754 status_t retval;
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
763 * April 21, 1998.
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 );
773 } else {
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 );
787 switch( the_id ) {
788 case B_ERROR:
789 sprintf( buff, "BeOS: Failed to load %.200s", fullpath );
790 break;
791 default:
792 sprintf( buff, "Unknown error loading %.200s", fullpath );
793 break;
796 PyErr_SetString( PyExc_ImportError, buff );
797 return NULL;
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 );
814 switch( retval ) {
815 case B_BAD_IMAGE_ID:
816 sprintf( buff, "can't load init function for dynamic module: "
817 "Invalid image ID for %.180s", fullpath );
818 break;
819 case B_BAD_INDEX:
820 sprintf( buff, "can't load init function for dynamic module: "
821 "Bad index for %.180s", funcname );
822 break;
823 default:
824 sprintf( buff, "can't load init function for dynamic module: "
825 "Unknown error looking up %.180s", funcname );
826 break;
829 retval = unload_add_on( the_id );
831 PyErr_SetString( PyExc_ImportError, buff );
832 return NULL;
835 /* Save the module name and image ID for later so we can clean up
836 * gracefully.
838 beos_add_dyn( name, the_id );
840 #endif /* __BEOS__ */
841 #ifdef USE_SHLIB
842 got_it:
843 #endif
844 if (p == NULL) {
845 PyErr_Format(PyExc_ImportError,
846 "dynamic module does not define init function (%.200s)",
847 funcname);
848 return NULL;
850 _Py_PackageContext = packagecontext;
851 (*p)();
852 _Py_PackageContext = NULL;
853 if (PyErr_Occurred())
854 return NULL;
855 if (_PyImport_FixupExtension(name, pathname) == NULL)
856 return NULL;
858 m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
859 if (m == NULL) {
860 PyErr_SetString(PyExc_SystemError,
861 "dynamic module not initialized properly");
862 return NULL;
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 */
869 Py_XDECREF(s);
870 if (Py_VerboseFlag)
871 PySys_WriteStderr(
872 "import %s # dynamically loaded from %s\n",
873 name, pathname);
874 Py_INCREF(m);
875 return m;
876 #endif /* DYNAMIC_LINK */
880 #ifdef _AIX
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 {
888 struct Module *next;
889 void *entry;
890 } Module, *ModulePtr;
892 static int
893 aix_getoldmodules(modlistptr)
894 void **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));
907 return -1;
909 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
910 && errno == ENOMEM) {
911 free(ldibuf);
912 bufsize += 1024;
913 if ((ldibuf = malloc(bufsize)) == NULL) {
914 PyErr_SetString(PyExc_ImportError, strerror(errno));
915 return -1;
918 if (errflag == -1) {
919 PyErr_SetString(PyExc_ImportError, strerror(errno));
920 return -1;
923 -- Make the modules list from the ld_info structures.
925 ldiptr = (struct ld_info *)ldibuf;
926 prevmodptr = NULL;
927 do {
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)
936 ldiptr + offset);
937 continue;
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;
944 free(modptr);
946 return -1;
948 modptr->entry = ldiptr->ldinfo_dataorg;
949 modptr->next = NULL;
950 if (prevmodptr == NULL)
951 *modlistptr = (void *)modptr;
952 else
953 prevmodptr->next = modptr;
954 prevmodptr = modptr;
955 offset = (unsigned int)ldiptr->ldinfo_next;
956 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
957 } while (offset);
958 free(ldibuf);
959 return 0;
962 static int
963 aix_bindnewmodule(newmoduleptr, modlistptr)
964 void *newmoduleptr;
965 void *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)
974 return -1;
975 return 0;
978 static void
979 aix_loaderror(pathname)
980 char *pathname;
983 char *message[1024], errbuf[1024];
984 register int i,j;
986 struct errtab {
987 int errNo;
988 char *errstr;
989 } load_errtab[] = {
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:"},
993 {L_ERROR_RLDBAD,
994 "RLD index out of range or bad relocation type:"},
995 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
996 {L_ERROR_MEMBER,
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);
1025 return;
1028 #endif /* _AIX */
1030 #ifdef __BEOS__
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().
1050 * [chrish]
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
1059 * variable.
1061 static int32 init_count = 0;
1062 int32 val;
1064 val = atomic_add( &init_count, 1 );
1065 if( beos_dyn_images == NULL && val == 0 ) {
1066 beos_dyn_images = PyDict_New();
1067 #ifdef WITH_THREAD
1068 beos_dyn_lock = PyThread_allocate_lock();
1069 #endif
1070 atexit( beos_cleanup_dyn );
1074 /* atexit() handler that'll call unload_add_on() for every item in the
1075 * dictionary.
1077 static void beos_cleanup_dyn( void )
1079 if( beos_dyn_images ) {
1080 int idx;
1081 int list_size;
1082 PyObject *id_list;
1084 #ifdef WITH_THREAD
1085 PyThread_acquire_lock( beos_dyn_lock, 1 );
1086 #endif
1088 id_list = PyDict_Values( beos_dyn_images );
1090 list_size = PyList_Size( id_list );
1091 for( idx = 0; idx < list_size; idx++ ) {
1092 PyObject *the_item;
1094 the_item = PyList_GetItem( id_list, idx );
1095 beos_nuke_dyn( the_item );
1098 PyDict_Clear( beos_dyn_images );
1100 #ifdef WITH_THREAD
1101 PyThread_free_lock( beos_dyn_lock );
1102 #endif
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 )
1111 status_t retval;
1113 if( 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 )
1128 int retval;
1129 PyObject *py_id;
1131 if( beos_dyn_images == NULL ) {
1132 beos_init_dyn();
1135 #ifdef WITH_THREAD
1136 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1137 #endif
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 );
1143 if( py_id ) {
1144 beos_nuke_dyn( py_id );
1145 retval = PyDict_DelItemString( beos_dyn_images, name );
1148 py_id = PyInt_FromLong( (long)id );
1149 if( py_id ) {
1150 retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
1153 #ifdef WITH_THREAD
1154 PyThread_release_lock( beos_dyn_lock );
1155 #endif
1158 #endif /* __BEOS__ */