blob: dc97f67f188f329982d9b40bd28db9ba58deb348 [file] [log] [blame]
Guido van Rossum1ae940a1995-01-02 19:04:15 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum1ae940a1995-01-02 19:04:15 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum1ae940a1995-01-02 19:04:15 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum1ae940a1995-01-02 19:04:15 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum1ae940a1995-01-02 19:04:15 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum1ae940a1995-01-02 19:04:15 +000029
30******************************************************************/
31
32/* Support for dynamic loading of extension modules */
33/* If no dynamic linking is supported, this file still generates some code! */
34
Guido van Rossum79f25d91997-04-29 20:08:16 +000035#include "Python.h"
Guido van Rossumcecadc41998-04-10 23:45:14 +000036
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
Guido van Rossum1ae940a1995-01-02 19:04:15 +000041#include "osdefs.h"
42#include "importdl.h"
43
Guido van Rossum1ae940a1995-01-02 19:04:15 +000044/* Explanation of some of the the various #defines used by dynamic linking...
45
46 symbol -- defined for:
47
48 DYNAMIC_LINK -- any kind of dynamic linking
Guido van Rossum75f288d1995-06-14 22:07:26 +000049 USE_RLD -- NeXT dynamic linking
Guido van Rossum1ae940a1995-01-02 19:04:15 +000050 USE_DL -- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
51 USE_SHLIB -- SunOS or IRIX 5 (SVR4?) shared libraries
52 _AIX -- AIX style dynamic linking
Guido van Rossum9b38a141996-09-11 23:12:24 +000053 MS_WIN32 -- Windows NT style dynamic linking (using DLLs)
54 MS_WIN16 -- Windows 16-bit dynamic linking (using DLLs)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000055 PYOS_OS2 -- IBM OS/2 dynamic linking (using DLLs)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000056 _DL_FUNCPTR_DEFINED -- if the typedef dl_funcptr has been defined
Jack Jansen5d9acb61995-06-14 14:54:25 +000057 USE_MAC_DYNAMIC_LOADING -- Mac CFM shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000058 SHORT_EXT -- short extension for dynamic module, e.g. ".so"
59 LONG_EXT -- long extension, e.g. "module.so"
60 hpux -- HP-UX Dynamic Linking - defined by the compiler
Guido van Rossum15af20a1998-01-19 22:03:52 +000061 __NetBSD__ -- NetBSD shared libraries
62 (assuming dlerror() was introduced between 1.2 and 1.3)
Guido van Rossum25e85291996-02-25 05:02:29 +000063 __FreeBSD__ -- FreeBSD shared libraries
Guido van Rossum1a8791e1998-08-04 22:46:29 +000064 __BEOS__ -- BeOS shared libraries - defined by the compiler
Guido van Rossum1ae940a1995-01-02 19:04:15 +000065
66 (The other WITH_* symbols are used only once, to set the
67 appropriate symbols.)
68*/
69
70/* Configure dynamic linking */
71
Guido van Rossumff4af061996-01-12 01:17:50 +000072#ifdef __hpux
Guido van Rossum1e612491996-08-19 22:12:10 +000073#ifndef hpux
Guido van Rossumff4af061996-01-12 01:17:50 +000074#define hpux
75#endif
Guido van Rossum1e612491996-08-19 22:12:10 +000076#endif
Guido van Rossumff4af061996-01-12 01:17:50 +000077
Guido van Rossum1ae940a1995-01-02 19:04:15 +000078#ifdef hpux
79#define DYNAMIC_LINK
80#include <errno.h>
81typedef void (*dl_funcptr)();
82#define _DL_FUNCPTR_DEFINED 1
83#define SHORT_EXT ".sl"
84#define LONG_EXT "module.sl"
85#endif
86
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000087#if defined(PYOS_OS2)
88#define DYNAMIC_LINK
89#define INCL_DOSERRORS
90#define INCL_DOSMODULEMGR
91#include <os2.h>
92typedef int (* APIENTRY dl_funcptr)();
93#define _DL_FUNCPTR_DEFINED 1
94#define SHORT_EXT ".pyd"
95#define LONG_EXT ".dll"
96#endif
97
Guido van Rossum15af20a1998-01-19 22:03:52 +000098#if defined(__NetBSD__) && (NetBSD < 199712)
Guido van Rossum46c76a61995-01-20 16:53:54 +000099#define DYNAMIC_LINK
100#define USE_SHLIB
101
102#define dlerror() "error in dynamic linking"
103#endif
104
Guido van Rossum9b38a141996-09-11 23:12:24 +0000105#ifdef MS_WINDOWS /* i.e. MS_WIN32 or MS_WIN16 */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000106#define DYNAMIC_LINK
107#include <windows.h>
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000108#include <direct.h>
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000109typedef FARPROC dl_funcptr;
110#define _DL_FUNCPTR_DEFINED
Guido van Rossum859b16c1998-05-15 20:22:08 +0000111#ifdef _DEBUG
112#define SHORT_EXT "_d.pyd"
113#define LONG_EXT "_d.dll"
114#else
Guido van Rossum5fb1da71995-01-07 12:36:02 +0000115#define SHORT_EXT ".pyd"
Guido van Rossume71a9471996-04-09 02:39:15 +0000116#define LONG_EXT ".dll"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000117#endif
Guido van Rossum859b16c1998-05-15 20:22:08 +0000118#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000119
Guido van Rossum75f288d1995-06-14 22:07:26 +0000120#ifdef NeXT
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000121#define DYNAMIC_LINK
122#define USE_RLD
Guido van Rossumab076fd1998-08-24 14:15:44 +0000123/* Define this to 1 if you want be able to load ObjC modules as well:
124 it switches between two different way of loading modules on the NeXT,
125 one that directly interfaces with the dynamic loader (rld_load(), which
126 does not correctly load ObjC object files), and another that uses the
127 ObjC runtime (objc_loadModules()) to do the job.
128 You'll have to add ``-ObjC'' to the compiler flags if you set this to 1.
129*/
130#define HANDLE_OBJC_MODULES 1
131#if HANDLE_OBJC_MODULES
132#include <objc/Object.h>
133#include <objc/objc-load.h>
134#endif
Guido van Rossum54dec591997-08-16 14:38:09 +0000135#define SHORT_EXT ".so"
136#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000137#endif
138
139#ifdef WITH_SGI_DL
140#define DYNAMIC_LINK
141#define USE_DL
142#endif
143
144#ifdef WITH_DL_DLD
145#define DYNAMIC_LINK
146#define USE_DL
147#endif
148
Jack Jansen5d9acb61995-06-14 14:54:25 +0000149#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen4e043731995-02-13 22:42:34 +0000150#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000151#define SHORT_EXT ".slb"
Guido van Rossum1e612491996-08-19 22:12:10 +0000152#ifdef __CFM68K__
153#define LONG_EXT ".CFM68K.slb"
154#else
155#define LONG_EXT ".ppc.slb"
156#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000157#ifndef _DL_FUNCPTR_DEFINED
158typedef void (*dl_funcptr)();
159#endif
160#endif
161
Guido van Rossum504f4a91996-08-20 19:59:07 +0000162#if !defined(DYNAMIC_LINK) && (defined(HAVE_DLOPEN) || defined(M_UNIX))
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000163#define DYNAMIC_LINK
164#define USE_SHLIB
165#endif
166
167#ifdef _AIX
Guido van Rossumef3d02e1997-07-21 14:54:36 +0000168#undef USE_SHLIB /* AIX 4.2 and higher have dlfcn.h but we don't want it */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000169#define DYNAMIC_LINK
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000170#define SHORT_EXT ".so"
171#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000172#include <sys/ldr.h>
173typedef void (*dl_funcptr)();
174#define _DL_FUNCPTR_DEFINED
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000175static int aix_getoldmodules(void **);
176static int aix_bindnewmodule(void *, void *);
177static void aix_loaderror(char *);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000178#endif
179
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000180#ifdef __BEOS__
Guido van Rossume364b7d1998-10-01 20:43:23 +0000181#undef USE_SHLIB /* probably not defined anyway */
182#define DYNAMIC_LINK
183#define SHORT_EXT ".so"
184#define LONG_EXT "module.so"
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000185typedef void (*dl_funcptr)(void);
Guido van Rossume364b7d1998-10-01 20:43:23 +0000186#define _DL_FUNCPTR_DEFINED
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000187
Guido van Rossume364b7d1998-10-01 20:43:23 +0000188#if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
189#undef MAXPATHLEN
190#endif
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000191
Guido van Rossume364b7d1998-10-01 20:43:23 +0000192#include <kernel/image.h>
193#include <kernel/OS.h>
194#include <stdlib.h>
195#include <unistd.h>
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000196
Guido van Rossume364b7d1998-10-01 20:43:23 +0000197#ifdef WITH_THREAD
198#include "pythread.h"
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000199static type_lock beos_dyn_lock;
Guido van Rossume364b7d1998-10-01 20:43:23 +0000200#endif
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000201
202static PyObject *beos_dyn_images = NULL;
203
204static void beos_init_dyn( void );
205static void beos_cleanup_dyn( void );
206static void beos_nuke_dyn( PyObject *item );
207static void beos_add_dyn( char *pathname, image_id id );
208
209/* External interface for finding image IDs; useful if you need to
210 * do your own symbol lookup in dynamically loaded modules. [Donn Cave]
211 *
212 * Hmm, could we hack up the Sun dlmodule instead for this sort of thing?
213 * That might be more generally useful. [chrish]
214 */
215image_id PyImport_BeImageID( char *name );
216#endif
217
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000218#ifdef DYNAMIC_LINK
219
220#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000221#include <sys/types.h>
222#include <sys/stat.h>
Guido van Rossum15af20a1998-01-19 22:03:52 +0000223#if defined(__NetBSD__) && (NetBSD < 199712)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000224#include <nlist.h>
225#include <link.h>
226#else
Guido van Rossum504f4a91996-08-20 19:59:07 +0000227#ifdef HAVE_DLFCN_H
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000228#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000229#endif
Guido van Rossum504f4a91996-08-20 19:59:07 +0000230#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000231#ifndef _DL_FUNCPTR_DEFINED
232typedef void (*dl_funcptr)();
233#endif
234#ifndef RTLD_LAZY
235#define RTLD_LAZY 1
236#endif
237#define SHORT_EXT ".so"
238#define LONG_EXT "module.so"
239#endif /* USE_SHLIB */
240
241#if defined(USE_DL) || defined(hpux)
242#include "dl.h"
243#endif
244
Jack Jansen5d9acb61995-06-14 14:54:25 +0000245#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000246#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000247#include <CodeFragments.h>
Guido van Rossum79f25d91997-04-29 20:08:16 +0000248#ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000249#define CFragConnectionID ConnectionID
250#define kLoadCFrag 0x01
251#endif
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000252#ifdef USE_GUSI
253#include "TFileSpec.h" /* for Path2FSSpec() */
254#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000255#include <Files.h>
256#include "macdefs.h"
257#include "macglue.h"
258#endif
259
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000260#ifdef USE_RLD
261#include <mach-o/rld.h>
262#define FUNCNAME_PATTERN "_init%.200s"
263#ifndef _DL_FUNCPTR_DEFINED
264typedef void (*dl_funcptr)();
265#endif
266#endif /* USE_RLD */
267
Guido van Rossum79f25d91997-04-29 20:08:16 +0000268extern char *Py_GetProgramName();
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000269
270#ifndef FUNCNAME_PATTERN
Guido van Rossum65f15d41998-09-30 14:34:52 +0000271#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) && !defined(__ELF__) || defined(__OpenBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000272#define FUNCNAME_PATTERN "_init%.200s"
273#else
274#define FUNCNAME_PATTERN "init%.200s"
275#endif
276#endif
277
278#if !defined(SHORT_EXT) && !defined(LONG_EXT)
279#define SHORT_EXT ".o"
280#define LONG_EXT "module.o"
281#endif /* !SHORT_EXT && !LONG_EXT */
282
283#endif /* DYNAMIC_LINK */
284
Guido van Rossum79f25d91997-04-29 20:08:16 +0000285struct filedescr _PyImport_Filetab[] = {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000286#ifdef SHORT_EXT
287 {SHORT_EXT, "rb", C_EXTENSION},
288#endif /* !SHORT_EXT */
289#ifdef LONG_EXT
290 {LONG_EXT, "rb", C_EXTENSION},
291#endif /* !LONG_EXT */
292 {".py", "r", PY_SOURCE},
293 {".pyc", "rb", PY_COMPILED},
294 {0, 0}
295};
296
Guido van Rossum38234201996-07-31 17:55:19 +0000297#ifdef NO_DYNAMIC_LINK
298#undef DYNAMIC_LINK
299#endif
300
Guido van Rossum79f25d91997-04-29 20:08:16 +0000301PyObject *
302_PyImport_LoadDynamicModule(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000303 char *name;
304 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000305 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000306{
307#ifndef DYNAMIC_LINK
Guido van Rossum79f25d91997-04-29 20:08:16 +0000308 PyErr_SetString(PyExc_ImportError,
309 "dynamically linked modules not supported");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000310 return NULL;
311#else
Guido van Rossum79f25d91997-04-29 20:08:16 +0000312 PyObject *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000313 char funcname[258];
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000314 char *lastdot, *shortname, *packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000315 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000316#ifdef USE_SHLIB
317 static struct {
318 dev_t dev;
319 ino_t ino;
320 void *handle;
321 } handles[128];
322 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000323 char pathbuf[260];
324 if (strchr(pathname, '/') == NULL) {
325 /* Prefix bare filename with "./" */
326 sprintf(pathbuf, "./%-.255s", pathname);
327 pathname = pathbuf;
328 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000329#endif
Guido van Rossum25ce5661997-08-02 03:10:38 +0000330 if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
331 Py_INCREF(m);
332 return m;
333 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000334 lastdot = strrchr(name, '.');
335 if (lastdot == NULL) {
336 packagecontext = NULL;
337 shortname = name;
338 }
339 else {
340 packagecontext = name;
341 shortname = lastdot+1;
342 }
343 sprintf(funcname, FUNCNAME_PATTERN, shortname);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000344#ifdef USE_SHLIB
345 if (fp != NULL) {
346 int i;
347 struct stat statb;
348 fstat(fileno(fp), &statb);
349 for (i = 0; i < nhandles; i++) {
350 if (statb.st_dev == handles[i].dev &&
351 statb.st_ino == handles[i].ino) {
352 p = (dl_funcptr) dlsym(handles[i].handle,
353 funcname);
354 goto got_it;
355 }
356 }
357 if (nhandles < 128) {
358 handles[nhandles].dev = statb.st_dev;
359 handles[nhandles].ino = statb.st_ino;
360 }
361 }
362#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000363#ifdef USE_MAC_DYNAMIC_LOADING
364 /*
Guido van Rossum79f25d91997-04-29 20:08:16 +0000365 ** Dynamic loading of CFM shared libraries on the Mac. The
366 ** code has become more convoluted than it was, because we
367 ** want to be able to put multiple modules in a single
368 ** file. For this reason, we have to determine the fragment
369 ** name, and we cannot use the library entry point but we have
370 ** to locate the correct init routine "by hand".
Jack Jansen5d9acb61995-06-14 14:54:25 +0000371 */
Jack Jansen4e043731995-02-13 22:42:34 +0000372 {
373 FSSpec libspec;
374 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000375 Ptr mainAddr;
376 Str255 errMessage;
377 OSErr err;
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000378#ifndef USE_GUSI
Jack Jansen5d9acb61995-06-14 14:54:25 +0000379 Boolean isfolder, didsomething;
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000380#endif
Jack Jansen5d9acb61995-06-14 14:54:25 +0000381 char buf[512];
382 Str63 fragname;
383 Ptr symAddr;
384 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000385
Jack Jansen5d9acb61995-06-14 14:54:25 +0000386 /* First resolve any aliases to find the real file */
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000387#ifdef USE_GUSI
388 err = Path2FSSpec(pathname, &libspec);
389#else
Jack Jansen4e043731995-02-13 22:42:34 +0000390 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000391 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000392#endif
Jack Jansen5d9acb61995-06-14 14:54:25 +0000393 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000394 sprintf(buf, "%.255s: %.200s",
395 pathname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000396 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000397 return NULL;
398 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000399 /* Next, determine the fragment name,
400 by stripping '.slb' and 'module' */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000401 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
402 fragname[0] = libspec.name[0];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000403 if( strncmp((char *)(fragname+1+fragname[0]-4),
404 ".slb", 4) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000405 fragname[0] -= 4;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000406 if ( strncmp((char *)(fragname+1+fragname[0]-6),
407 "module", 6) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000408 fragname[0] -= 6;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000409 /* Load the fragment
410 (or return the connID if it is already loaded */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000411 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000412 kLoadCFrag, &connID, &mainAddr,
413 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000414 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000415 sprintf(buf, "%.*s: %.200s",
416 errMessage[0], errMessage+1,
Guido van Rossum79f25d91997-04-29 20:08:16 +0000417 PyMac_StrError(err));
418 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen4e043731995-02-13 22:42:34 +0000419 return NULL;
420 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000421 /* Locate the address of the correct init function */
422 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
423 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000424 sprintf(buf, "%s: %.200s",
425 funcname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000426 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000427 return NULL;
428 }
429 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000430 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000431#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000432#ifdef USE_SHLIB
433 {
434#ifdef RTLD_NOW
435 /* RTLD_NOW: resolve externals now
436 (i.e. core dump now if some are missing) */
Guido van Rossum6b077871998-05-18 13:42:45 +0000437 void *handle = dlopen(pathname, RTLD_NOW);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000438#else
439 void *handle;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000440 if (Py_VerboseFlag)
Guido van Rossum08052c71997-12-02 20:43:18 +0000441 printf("dlopen(\"%s\", %d);\n", pathname,
Guido van Rossum6b077871998-05-18 13:42:45 +0000442 RTLD_LAZY);
443 handle = dlopen(pathname, RTLD_LAZY);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000444#endif /* RTLD_NOW */
445 if (handle == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000446 PyErr_SetString(PyExc_ImportError, dlerror());
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000447 return NULL;
448 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000449 if (fp != NULL && nhandles < 128)
450 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000451 p = (dl_funcptr) dlsym(handle, funcname);
452 }
453#endif /* USE_SHLIB */
454#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000455 /*
456 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
457 -- of the shared module unresolved. Thus we have to resolve them
458 -- explicitely with loadbind. The new module is loaded, then we
459 -- resolve its symbols using the list of already loaded modules
460 -- (only those that belong to the python executable). Get these
461 -- with loadquery(L_GETINFO).
462 */
463 {
464 static void *staticmodlistptr = NULL;
465
466 if (!staticmodlistptr)
467 if (aix_getoldmodules(&staticmodlistptr) == -1)
468 return NULL;
469 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
470 if (p == NULL) {
471 aix_loaderror(pathname);
472 return NULL;
473 }
474 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
475 aix_loaderror(pathname);
476 return NULL;
477 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000478 }
479#endif /* _AIX */
Guido van Rossum9b38a141996-09-11 23:12:24 +0000480#ifdef MS_WIN32
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000481 {
482 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000483 char pathbuf[260];
484 if (strchr(pathname, SEP) == NULL &&
485 strchr(pathname, ALTSEP) == NULL)
486 {
487 /* Prefix bare filename with ".\" */
488 char *p = pathbuf;
489 *p = '\0';
490 _getcwd(pathbuf, sizeof pathbuf);
491 if (*p != '\0' && p[1] == ':')
492 p += 2;
493 sprintf(p, ".\\%-.255s", pathname);
494 pathname = pathbuf;
495 }
Guido van Rossum0f8b30f1998-10-08 01:44:41 +0000496 /* Look for dependent DLLs in directory of pathname first */
497 /* XXX This call doesn't exist in Windows CE */
498 hDLL = LoadLibraryEx(pathname, NULL,
499 LOAD_WITH_ALTERED_SEARCH_PATH);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000500 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000501 char errBuf[256];
502 unsigned int errorCode;
503
504 /* Get an error string from Win32 error code */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000505 char theInfo[256]; /* Pointer to error text
506 from system */
507 int theLength; /* Length of error text */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000508
509 errorCode = GetLastError();
510
Guido van Rossum79f25d91997-04-29 20:08:16 +0000511 theLength = FormatMessage(
512 FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
513 NULL, /* message source */
514 errorCode, /* the message (error) ID */
515 0, /* default language environment */
516 (LPTSTR) theInfo, /* the buffer */
517 sizeof(theInfo), /* the buffer size */
518 NULL); /* no additional format args. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000519
Guido van Rossum79f25d91997-04-29 20:08:16 +0000520 /* Problem: could not get the error message.
521 This should not happen if called correctly. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000522 if (theLength == 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000523 sprintf(errBuf,
524 "DLL load failed with error code %d",
525 errorCode);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000526 } else {
527 int len;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000528 /* For some reason a \r\n
529 is appended to the text */
530 if (theLength >= 2 &&
531 theInfo[theLength-2] == '\r' &&
532 theInfo[theLength-1] == '\n') {
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000533 theLength -= 2;
534 theInfo[theLength] = '\0';
535 }
536 strcpy(errBuf, "DLL load failed: ");
537 len = strlen(errBuf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000538 strncpy(errBuf+len, theInfo,
539 sizeof(errBuf)-len);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000540 errBuf[sizeof(errBuf)-1] = '\0';
541 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000542 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000543 return NULL;
544 }
545 p = GetProcAddress(hDLL, funcname);
546 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000547#endif /* MS_WIN32 */
548#ifdef MS_WIN16
Guido van Rossumdadc8241996-05-23 22:51:40 +0000549 {
550 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000551 char pathbuf[16];
552 if (strchr(pathname, SEP) == NULL &&
553 strchr(pathname, ALTSEP) == NULL)
554 {
555 /* Prefix bare filename with ".\" */
556 sprintf(pathbuf, ".\\%-.13s", pathname);
557 pathname = pathbuf;
558 }
Guido van Rossumdadc8241996-05-23 22:51:40 +0000559 hDLL = LoadLibrary(pathname);
560 if (hDLL < HINSTANCE_ERROR){
561 char errBuf[256];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000562 sprintf(errBuf,
563 "DLL load failed with error code %d", hDLL);
564 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossumdadc8241996-05-23 22:51:40 +0000565 return NULL;
566 }
567 p = GetProcAddress(hDLL, funcname);
568 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000569#endif /* MS_WIN16 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000570
571#if defined(PYOS_OS2)
572 {
573 APIRET rc;
574 HMODULE hDLL;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000575 char failreason[256];
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000576
577 rc = DosLoadModule(failreason,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000578 sizeof(failreason),
579 pathname,
580 &hDLL);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000581
582 if (rc != NO_ERROR) {
583 char errBuf[256];
584 sprintf(errBuf,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000585 "DLL load failed, rc = %d, problem '%s': %s",
586 rc, failreason);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000587 PyErr_SetString(PyExc_ImportError, errBuf);
588 return NULL;
589 }
590
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000591 rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
592 if (rc != NO_ERROR)
593 p = NULL; /* Signify Failure to Acquire Entrypoint */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000594 }
595#endif /* PYOS_OS2 */
596
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000597#ifdef USE_DL
Guido van Rossum79f25d91997-04-29 20:08:16 +0000598 p = dl_loadmod(Py_GetProgramName(), pathname, funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000599#endif /* USE_DL */
600#ifdef USE_RLD
601 {
602 NXStream *errorStream;
603 struct mach_header *new_header;
604 const char *filenames[2];
605 long ret;
606 unsigned long ptr;
607
608 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
609 filenames[0] = pathname;
610 filenames[1] = NULL;
Guido van Rossumab076fd1998-08-24 14:15:44 +0000611
612#if HANDLE_OBJC_MODULES
613
614/* The following very bogus line of code ensures that
615 objc_msgSend, etc are linked into the binary. Without
616 it, dynamic loading of a module that includes objective-c
617 method calls will fail with "undefined symbol _objc_msgSend()".
618 This remains true even in the presence of the -ObjC flag
619 to the compiler
620*/
621
622 [Object name];
623
624/* objc_loadModules() dynamically loads the object files
625 indicated by the paths in filenames. If there are any
626 errors generated during loading -- typically due to the
627 inability to find particular symbols -- an error message
628 will be written to errorStream.
629 It returns 0 if the module is successfully loaded, 1
630 otherwise.
631*/
632
633 ret = !objc_loadModules(filenames, errorStream,
634 NULL, &new_header, NULL);
635
636#else /* !HANDLE_OBJC_MODULES */
637
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000638 ret = rld_load(errorStream, &new_header,
639 filenames, NULL);
640
Guido van Rossumab076fd1998-08-24 14:15:44 +0000641#endif /* HANDLE_OBJC_MODULES */
642
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000643 /* extract the error messages for the exception */
644 if(!ret) {
645 char *streamBuf;
646 int len, maxLen;
647
648 NXPutc(errorStream, (char)0);
649
650 NXGetMemoryBuffer(errorStream,
651 &streamBuf, &len, &maxLen);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000652 PyErr_SetString(PyExc_ImportError, streamBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000653 }
654
655 if(ret && rld_lookup(errorStream, funcname, &ptr))
656 p = (dl_funcptr) ptr;
657
658 NXCloseMemory(errorStream, NX_FREEBUFFER);
659
660 if(!ret)
661 return NULL;
662 }
663#endif /* USE_RLD */
664#ifdef hpux
665 {
666 shl_t lib;
667 int flags;
668
Guido van Rossum3afb5951996-12-05 23:15:35 +0000669 flags = BIND_FIRST | BIND_DEFERRED;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000670 if (Py_VerboseFlag) {
671 flags = DYNAMIC_PATH | BIND_FIRST | BIND_IMMEDIATE |
Guido van Rossum79f25d91997-04-29 20:08:16 +0000672 BIND_NONFATAL | BIND_VERBOSE;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000673 printf("shl_load %s\n",pathname);
674 }
675 lib = shl_load(pathname, flags, 0);
676 /* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
677 if (lib == NULL) {
678 char buf[256];
679 if (Py_VerboseFlag)
680 perror(pathname);
681 sprintf(buf, "Failed to load %.200s", pathname);
682 PyErr_SetString(PyExc_ImportError, buf);
683 return NULL;
684 }
685 if (Py_VerboseFlag)
686 printf("shl_findsym %s\n", funcname);
687 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
688 if (p == NULL && Py_VerboseFlag)
689 perror(funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000690 }
691#endif /* hpux */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000692#ifdef __BEOS__
693 {
694 image_id the_id;
695 status_t retval;
696 char fullpath[PATH_MAX];
697
698 if( Py_VerboseFlag ) {
699 printf( "load_add_on( %s )\n", pathname );
700 }
701
702 /* Hmm, this old bug appears to have regenerated itself; if the
703 * path isn't absolute, load_add_on() will fail. Reported to Be
704 * April 21, 1998.
705 */
706 if( pathname[0] != '/' ) {
707 (void)getcwd( fullpath, PATH_MAX );
708 (void)strncat( fullpath, "/", PATH_MAX );
709 (void)strncat( fullpath, pathname, PATH_MAX );
710
711 if( Py_VerboseFlag ) {
712 printf( "load_add_on( %s )\n", fullpath );
713 }
714 } else {
715 (void)strcpy( fullpath, pathname );
716 }
717
718 the_id = load_add_on( fullpath );
719 if( the_id < B_NO_ERROR ) {
720 /* It's too bad load_add_on() doesn't set errno or something...
721 */
722 char buff[256]; /* hate hard-coded string sizes... */
723
724 if( Py_VerboseFlag ) {
725 printf( "load_add_on( %s ) failed", fullpath );
726 }
727
728 switch( the_id ) {
729 case B_ERROR:
730 sprintf( buff, "BeOS: Failed to load %.200s", fullpath );
731 break;
732 default:
733 sprintf( buff, "Unknown error loading %.200s", fullpath );
734 break;
735 }
736
737 PyErr_SetString( PyExc_ImportError, buff );
738 return NULL;
739 }
740
741 if( Py_VerboseFlag ) {
742 printf( "get_image_symbol( %s )\n", funcname );
743 }
744
745 retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
746 if( retval != B_NO_ERROR || p == NULL ) {
747 /* That's bad, we can't find that symbol in the module...
748 */
749 char buff[256]; /* hate hard-coded string sizes... */
750
751 if( Py_VerboseFlag ) {
752 printf( "get_image_symbol( %s ) failed", funcname );
753 }
754
755 switch( retval ) {
756 case B_BAD_IMAGE_ID:
757 sprintf( buff, "can't load init function for dynamic module: "
758 "Invalid image ID for %.180s", fullpath );
759 break;
760 case B_BAD_INDEX:
761 sprintf( buff, "can't load init function for dynamic module: "
762 "Bad index for %.180s", funcname );
763 break;
764 default:
765 sprintf( buff, "can't load init function for dynamic module: "
766 "Unknown error looking up %.180s", funcname );
767 break;
768 }
769
770 retval = unload_add_on( the_id );
771
772 PyErr_SetString( PyExc_ImportError, buff );
773 return NULL;
774 }
775
776 /* Save the module name and image ID for later so we can clean up
777 * gracefully.
778 */
779 beos_add_dyn( name, the_id );
780 }
781#endif /* __BEOS__ */
Guido van Rossum644a12b1997-04-09 19:24:53 +0000782#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000783 got_it:
Guido van Rossum644a12b1997-04-09 19:24:53 +0000784#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000785 if (p == NULL) {
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000786 PyErr_Format(PyExc_ImportError,
Guido van Rossum42e8e5d1998-01-19 22:23:08 +0000787 "dynamic module does not define init function (%.200s)",
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000788 funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000789 return NULL;
790 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000791 _Py_PackageContext = packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000792 (*p)();
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000793 _Py_PackageContext = NULL;
Guido van Rossum25ce5661997-08-02 03:10:38 +0000794 if (PyErr_Occurred())
795 return NULL;
796 if (_PyImport_FixupExtension(name, pathname) == NULL)
797 return NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000798
Guido van Rossumef3d02e1997-07-21 14:54:36 +0000799 m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000800 if (m == NULL) {
Guido van Rossum25ce5661997-08-02 03:10:38 +0000801 PyErr_SetString(PyExc_SystemError,
802 "dynamic module not initialized properly");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000803 return NULL;
804 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000805 /* Remember the filename as the __file__ attribute */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000806 d = PyModule_GetDict(m);
807 s = PyString_FromString(pathname);
808 if (s == NULL || PyDict_SetItemString(d, "__file__", s) != 0)
809 PyErr_Clear(); /* Not important enough to report */
810 Py_XDECREF(s);
811 if (Py_VerboseFlag)
Guido van Rossum2f3667a1998-10-12 18:23:55 +0000812 PySys_WriteStderr(
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000813 "import %s # dynamically loaded from %s\n",
814 name, pathname);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000815 Py_INCREF(m);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000816 return m;
817#endif /* DYNAMIC_LINK */
818}
819
820
821#ifdef _AIX
822
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000823#include <ctype.h> /* for isdigit() */
824#include <errno.h> /* for global errno */
825#include <string.h> /* for strerror() */
826#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000827
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000828typedef struct Module {
829 struct Module *next;
830 void *entry;
831} Module, *ModulePtr;
832
833static int
834aix_getoldmodules(modlistptr)
835 void **modlistptr;
836{
837 register ModulePtr modptr, prevmodptr;
838 register struct ld_info *ldiptr;
839 register char *ldibuf;
840 register int errflag, bufsize = 1024;
841 register unsigned int offset;
842
843 /*
844 -- Get the list of loaded modules into ld_info structures.
845 */
846 if ((ldibuf = malloc(bufsize)) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000847 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000848 return -1;
849 }
850 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
851 && errno == ENOMEM) {
852 free(ldibuf);
853 bufsize += 1024;
854 if ((ldibuf = malloc(bufsize)) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000855 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000856 return -1;
857 }
858 }
859 if (errflag == -1) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000860 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000861 return -1;
862 }
863 /*
864 -- Make the modules list from the ld_info structures.
865 */
866 ldiptr = (struct ld_info *)ldibuf;
867 prevmodptr = NULL;
868 do {
Guido van Rossum3b31cd21997-10-10 17:40:00 +0000869 if (strstr(ldiptr->ldinfo_filename, "python") == NULL) {
870 /*
871 -- Extract only the modules containing "python" as a
872 -- substring, like the "python[version]" executable or
873 -- "libpython[version].a" in case python is embedded.
874 */
875 offset = (unsigned int)ldiptr->ldinfo_next;
876 ldiptr = (struct ld_info *)((unsigned int)
877 ldiptr + offset);
878 continue;
879 }
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000880 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000881 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000882 while (*modlistptr) {
883 modptr = (ModulePtr)*modlistptr;
884 *modlistptr = (void *)modptr->next;
885 free(modptr);
886 }
887 return -1;
888 }
889 modptr->entry = ldiptr->ldinfo_dataorg;
890 modptr->next = NULL;
891 if (prevmodptr == NULL)
892 *modlistptr = (void *)modptr;
893 else
894 prevmodptr->next = modptr;
895 prevmodptr = modptr;
896 offset = (unsigned int)ldiptr->ldinfo_next;
897 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
898 } while (offset);
899 free(ldibuf);
900 return 0;
901}
902
903static int
904aix_bindnewmodule(newmoduleptr, modlistptr)
905 void *newmoduleptr;
906 void *modlistptr;
907{
908 register ModulePtr modptr;
909
910 /*
911 -- Bind the new module with the list of loaded modules.
912 */
913 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
914 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
915 return -1;
916 return 0;
917}
918
919static void
920aix_loaderror(pathname)
921 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000922{
923
Guido van Rossum236f62d1996-06-26 21:07:08 +0000924 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000925 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000926
927 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000928 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000929 char *errstr;
930 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000931 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000932 {L_ERROR_NOLIB, "can't load library:"},
933 {L_ERROR_UNDEF, "can't find symbol in library:"},
934 {L_ERROR_RLDBAD,
935 "RLD index out of range or bad relocation type:"},
936 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
937 {L_ERROR_MEMBER,
938 "file not an archive or does not contain requested member:"},
939 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000940 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000941 {L_ERROR_SYSTEM, "System error:"},
942 {L_ERROR_ERRNO, NULL}
943 };
944
945#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
946#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
947
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000948 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000949
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000950 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000951 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000952 ERRBUF_APPEND("\n");
953 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000954 for(i = 0; message[i] && *message[i]; i++) {
955 int nerr = atoi(message[i]);
956 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000957 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000958 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000959 }
960 while (isdigit(*message[i])) message[i]++ ;
961 ERRBUF_APPEND(message[i]);
962 ERRBUF_APPEND("\n");
963 }
964 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000965 PyErr_SetString(PyExc_ImportError, errbuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000966 return;
967}
968
969#endif /* _AIX */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000970
971#ifdef __BEOS__
972/* ----------------------------------------------------------------------
973 * BeOS dynamic loading support
974 *
975 * This uses shared libraries, but BeOS has its own way of doing things
976 * (much easier than dlfnc.h, from the look of things). We'll use a
977 * Python Dictionary object to store the images_ids so we can be very
978 * nice and unload them when we exit.
979 *
980 * Note that this is thread-safe. Probably irrelevent, because of losing
981 * systems... Python probably disables threads while loading modules.
982 * Note the use of "probably"! Better to be safe than sorry. [chrish]
983 *
984 * As of 1.5.1 this should also work properly when you've configured
985 * Python without thread support; the 1.5 version required it, which wasn't
986 * very friendly. Note that I haven't tested it without threading... why
987 * would you want to avoid threads on BeOS? [chrish]
988 */
989
990/*
991 * Initialize our dictionary, and the dictionary mutex.
992 */
993static void beos_init_dyn( void )
994{
995 /* We're protected from a race condition here by the atomic init_count
996 * variable.
997 */
998 static int32 init_count = 0;
999 int32 val;
1000
1001 val = atomic_add( &init_count, 1 );
1002 if( beos_dyn_images == NULL && val == 0 ) {
1003 beos_dyn_images = PyDict_New();
1004#ifdef WITH_THREAD
1005 beos_dyn_lock = PyThread_allocate_lock();
1006#endif
1007 atexit( beos_cleanup_dyn );
1008 }
1009}
1010
1011/* atexit() handler that'll call unload_add_on() for every item in the
1012 * dictionary.
1013 */
1014static void beos_cleanup_dyn( void )
1015{
1016 if( beos_dyn_images ) {
1017 int idx;
1018 int list_size;
1019 PyObject *id_list;
1020
1021#ifdef WITH_THREAD
1022 PyThread_acquire_lock( beos_dyn_lock, 1 );
1023#endif
1024
1025 id_list = PyDict_Values( beos_dyn_images );
1026
1027 list_size = PyList_Size( id_list );
1028 for( idx = 0; idx < list_size; idx++ ) {
1029 PyObject *the_item;
1030
1031 the_item = PyList_GetItem( id_list, idx );
1032 beos_nuke_dyn( the_item );
1033 }
1034
1035 PyDict_Clear( beos_dyn_images );
1036
1037#ifdef WITH_THREAD
1038 PyThread_free_lock( beos_dyn_lock );
1039#endif
1040 }
1041}
1042
1043/* Whack an item; the item is an image_id in disguise, so we'll call
1044 * unload_add_on() for it.
1045 */
1046static void beos_nuke_dyn( PyObject *item )
1047{
1048 status_t retval;
1049
1050 if( item ) {
1051 image_id id = (image_id)PyInt_AsLong( item );
1052
1053 retval = unload_add_on( id );
1054 }
1055}
1056
1057/*
1058 * Add an image_id to the dictionary; the module name of the loaded image
1059 * is the key. Note that if the key is already in the dict, we unload
1060 * that image; this should allow reload() to work on dynamically loaded
1061 * modules (super-keen!).
1062 */
1063static void beos_add_dyn( char *name, image_id id )
1064{
1065 int retval;
1066 PyObject *py_id;
1067
1068 if( beos_dyn_images == NULL ) {
1069 beos_init_dyn();
1070 }
1071
1072#ifdef WITH_THREAD
1073 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1074#endif
1075
1076 /* If there's already an object with this key in the dictionary,
1077 * we're doing a reload(), so let's nuke it.
1078 */
1079 py_id = PyDict_GetItemString( beos_dyn_images, name );
1080 if( py_id ) {
1081 beos_nuke_dyn( py_id );
1082 retval = PyDict_DelItemString( beos_dyn_images, name );
1083 }
1084
1085 py_id = PyInt_FromLong( (long)id );
1086 if( py_id ) {
1087 retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
1088 }
1089
1090#ifdef WITH_THREAD
1091 PyThread_release_lock( beos_dyn_lock );
1092#endif
1093}
1094
1095/* Given a module name, return the image_id (if it's a dynamically loaded
1096 * module). [Donn Cave]
1097 */
1098image_id PyImport_BeImageID( char *name )
1099{
1100 int retval;
1101 PyObject *py_id;
1102 long id;
1103
1104 if( !beos_dyn_images ) {
1105 return B_ERROR;
1106 }
1107
1108#ifdef WITH_THREAD
1109 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1110#endif
1111
1112 py_id = PyDict_GetItemString( beos_dyn_images, name );
1113 if( py_id ) {
1114 id = PyInt_AsLong( py_id );
1115 } else {
1116 id = B_ERROR;
1117 }
1118
1119#ifdef WITH_THREAD
1120 PyThread_release_lock( beos_dyn_lock );
1121#endif
1122
1123 return (image_id)id;
1124}
1125#endif /* __BEOS__ */