blob: ef015ad2ecd48ee8e30bc74073667c81444cde4a [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__
181# undef USE_SHLIB /* probably not defined anyway */
182# define DYNAMIC_LINK
183# define SHORT_EXT ".so"
184# define LONG_EXT "module.so"
185typedef void (*dl_funcptr)(void);
186# define _DL_FUNCPTR_DEFINED
187
188# if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
189# undef MAXPATHLEN
190# endif
191
192# include <kernel/image.h>
193# include <kernel/OS.h>
194# include <stdlib.h>
195# include <unistd.h>
196
197# ifdef WITH_THREAD
198# include "thread.h"
199static type_lock beos_dyn_lock;
200# endif
201
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
Jack Jansen4e043731995-02-13 22:42:34 +0000252#include <Files.h>
253#include "macdefs.h"
254#include "macglue.h"
255#endif
256
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000257#ifdef USE_RLD
258#include <mach-o/rld.h>
259#define FUNCNAME_PATTERN "_init%.200s"
260#ifndef _DL_FUNCPTR_DEFINED
261typedef void (*dl_funcptr)();
262#endif
263#endif /* USE_RLD */
264
Guido van Rossum79f25d91997-04-29 20:08:16 +0000265extern char *Py_GetProgramName();
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000266
267#ifndef FUNCNAME_PATTERN
Guido van Rossum1f740161998-04-13 15:27:21 +0000268#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000269#define FUNCNAME_PATTERN "_init%.200s"
270#else
271#define FUNCNAME_PATTERN "init%.200s"
272#endif
273#endif
274
275#if !defined(SHORT_EXT) && !defined(LONG_EXT)
276#define SHORT_EXT ".o"
277#define LONG_EXT "module.o"
278#endif /* !SHORT_EXT && !LONG_EXT */
279
280#endif /* DYNAMIC_LINK */
281
Guido van Rossum79f25d91997-04-29 20:08:16 +0000282struct filedescr _PyImport_Filetab[] = {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000283#ifdef SHORT_EXT
284 {SHORT_EXT, "rb", C_EXTENSION},
285#endif /* !SHORT_EXT */
286#ifdef LONG_EXT
287 {LONG_EXT, "rb", C_EXTENSION},
288#endif /* !LONG_EXT */
289 {".py", "r", PY_SOURCE},
290 {".pyc", "rb", PY_COMPILED},
291 {0, 0}
292};
293
Guido van Rossum38234201996-07-31 17:55:19 +0000294#ifdef NO_DYNAMIC_LINK
295#undef DYNAMIC_LINK
296#endif
297
Guido van Rossum79f25d91997-04-29 20:08:16 +0000298PyObject *
299_PyImport_LoadDynamicModule(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000300 char *name;
301 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000302 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000303{
304#ifndef DYNAMIC_LINK
Guido van Rossum79f25d91997-04-29 20:08:16 +0000305 PyErr_SetString(PyExc_ImportError,
306 "dynamically linked modules not supported");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000307 return NULL;
308#else
Guido van Rossum79f25d91997-04-29 20:08:16 +0000309 PyObject *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000310 char funcname[258];
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000311 char *lastdot, *shortname, *packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000312 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000313#ifdef USE_SHLIB
314 static struct {
315 dev_t dev;
316 ino_t ino;
317 void *handle;
318 } handles[128];
319 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000320 char pathbuf[260];
321 if (strchr(pathname, '/') == NULL) {
322 /* Prefix bare filename with "./" */
323 sprintf(pathbuf, "./%-.255s", pathname);
324 pathname = pathbuf;
325 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000326#endif
Guido van Rossum25ce5661997-08-02 03:10:38 +0000327 if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
328 Py_INCREF(m);
329 return m;
330 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000331 lastdot = strrchr(name, '.');
332 if (lastdot == NULL) {
333 packagecontext = NULL;
334 shortname = name;
335 }
336 else {
337 packagecontext = name;
338 shortname = lastdot+1;
339 }
340 sprintf(funcname, FUNCNAME_PATTERN, shortname);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000341#ifdef USE_SHLIB
342 if (fp != NULL) {
343 int i;
344 struct stat statb;
345 fstat(fileno(fp), &statb);
346 for (i = 0; i < nhandles; i++) {
347 if (statb.st_dev == handles[i].dev &&
348 statb.st_ino == handles[i].ino) {
349 p = (dl_funcptr) dlsym(handles[i].handle,
350 funcname);
351 goto got_it;
352 }
353 }
354 if (nhandles < 128) {
355 handles[nhandles].dev = statb.st_dev;
356 handles[nhandles].ino = statb.st_ino;
357 }
358 }
359#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000360#ifdef USE_MAC_DYNAMIC_LOADING
361 /*
Guido van Rossum79f25d91997-04-29 20:08:16 +0000362 ** Dynamic loading of CFM shared libraries on the Mac. The
363 ** code has become more convoluted than it was, because we
364 ** want to be able to put multiple modules in a single
365 ** file. For this reason, we have to determine the fragment
366 ** name, and we cannot use the library entry point but we have
367 ** to locate the correct init routine "by hand".
Jack Jansen5d9acb61995-06-14 14:54:25 +0000368 */
Jack Jansen4e043731995-02-13 22:42:34 +0000369 {
370 FSSpec libspec;
371 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000372 Ptr mainAddr;
373 Str255 errMessage;
374 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000375 Boolean isfolder, didsomething;
376 char buf[512];
377 Str63 fragname;
378 Ptr symAddr;
379 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000380
Jack Jansen5d9acb61995-06-14 14:54:25 +0000381 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000382 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000383 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
384 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000385 sprintf(buf, "%.255s: %.200s",
386 pathname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000387 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000388 return NULL;
389 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000390 /* Next, determine the fragment name,
391 by stripping '.slb' and 'module' */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000392 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
393 fragname[0] = libspec.name[0];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000394 if( strncmp((char *)(fragname+1+fragname[0]-4),
395 ".slb", 4) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000396 fragname[0] -= 4;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000397 if ( strncmp((char *)(fragname+1+fragname[0]-6),
398 "module", 6) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000399 fragname[0] -= 6;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000400 /* Load the fragment
401 (or return the connID if it is already loaded */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000402 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000403 kLoadCFrag, &connID, &mainAddr,
404 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000405 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000406 sprintf(buf, "%.*s: %.200s",
407 errMessage[0], errMessage+1,
Guido van Rossum79f25d91997-04-29 20:08:16 +0000408 PyMac_StrError(err));
409 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen4e043731995-02-13 22:42:34 +0000410 return NULL;
411 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000412 /* Locate the address of the correct init function */
413 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
414 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000415 sprintf(buf, "%s: %.200s",
416 funcname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000417 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000418 return NULL;
419 }
420 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000421 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000422#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000423#ifdef USE_SHLIB
424 {
425#ifdef RTLD_NOW
426 /* RTLD_NOW: resolve externals now
427 (i.e. core dump now if some are missing) */
Guido van Rossum6b077871998-05-18 13:42:45 +0000428 void *handle = dlopen(pathname, RTLD_NOW);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000429#else
430 void *handle;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000431 if (Py_VerboseFlag)
Guido van Rossum08052c71997-12-02 20:43:18 +0000432 printf("dlopen(\"%s\", %d);\n", pathname,
Guido van Rossum6b077871998-05-18 13:42:45 +0000433 RTLD_LAZY);
434 handle = dlopen(pathname, RTLD_LAZY);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000435#endif /* RTLD_NOW */
436 if (handle == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000437 PyErr_SetString(PyExc_ImportError, dlerror());
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000438 return NULL;
439 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000440 if (fp != NULL && nhandles < 128)
441 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000442 p = (dl_funcptr) dlsym(handle, funcname);
443 }
444#endif /* USE_SHLIB */
445#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000446 /*
447 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
448 -- of the shared module unresolved. Thus we have to resolve them
449 -- explicitely with loadbind. The new module is loaded, then we
450 -- resolve its symbols using the list of already loaded modules
451 -- (only those that belong to the python executable). Get these
452 -- with loadquery(L_GETINFO).
453 */
454 {
455 static void *staticmodlistptr = NULL;
456
457 if (!staticmodlistptr)
458 if (aix_getoldmodules(&staticmodlistptr) == -1)
459 return NULL;
460 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
461 if (p == NULL) {
462 aix_loaderror(pathname);
463 return NULL;
464 }
465 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
466 aix_loaderror(pathname);
467 return NULL;
468 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000469 }
470#endif /* _AIX */
Guido van Rossum9b38a141996-09-11 23:12:24 +0000471#ifdef MS_WIN32
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000472 {
473 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000474 char pathbuf[260];
475 if (strchr(pathname, SEP) == NULL &&
476 strchr(pathname, ALTSEP) == NULL)
477 {
478 /* Prefix bare filename with ".\" */
479 char *p = pathbuf;
480 *p = '\0';
481 _getcwd(pathbuf, sizeof pathbuf);
482 if (*p != '\0' && p[1] == ':')
483 p += 2;
484 sprintf(p, ".\\%-.255s", pathname);
485 pathname = pathbuf;
486 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000487 hDLL = LoadLibrary(pathname);
488 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000489 char errBuf[256];
490 unsigned int errorCode;
491
492 /* Get an error string from Win32 error code */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000493 char theInfo[256]; /* Pointer to error text
494 from system */
495 int theLength; /* Length of error text */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000496
497 errorCode = GetLastError();
498
Guido van Rossum79f25d91997-04-29 20:08:16 +0000499 theLength = FormatMessage(
500 FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
501 NULL, /* message source */
502 errorCode, /* the message (error) ID */
503 0, /* default language environment */
504 (LPTSTR) theInfo, /* the buffer */
505 sizeof(theInfo), /* the buffer size */
506 NULL); /* no additional format args. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000507
Guido van Rossum79f25d91997-04-29 20:08:16 +0000508 /* Problem: could not get the error message.
509 This should not happen if called correctly. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000510 if (theLength == 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000511 sprintf(errBuf,
512 "DLL load failed with error code %d",
513 errorCode);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000514 } else {
515 int len;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000516 /* For some reason a \r\n
517 is appended to the text */
518 if (theLength >= 2 &&
519 theInfo[theLength-2] == '\r' &&
520 theInfo[theLength-1] == '\n') {
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000521 theLength -= 2;
522 theInfo[theLength] = '\0';
523 }
524 strcpy(errBuf, "DLL load failed: ");
525 len = strlen(errBuf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000526 strncpy(errBuf+len, theInfo,
527 sizeof(errBuf)-len);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000528 errBuf[sizeof(errBuf)-1] = '\0';
529 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000530 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000531 return NULL;
532 }
533 p = GetProcAddress(hDLL, funcname);
534 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000535#endif /* MS_WIN32 */
536#ifdef MS_WIN16
Guido van Rossumdadc8241996-05-23 22:51:40 +0000537 {
538 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000539 char pathbuf[16];
540 if (strchr(pathname, SEP) == NULL &&
541 strchr(pathname, ALTSEP) == NULL)
542 {
543 /* Prefix bare filename with ".\" */
544 sprintf(pathbuf, ".\\%-.13s", pathname);
545 pathname = pathbuf;
546 }
Guido van Rossumdadc8241996-05-23 22:51:40 +0000547 hDLL = LoadLibrary(pathname);
548 if (hDLL < HINSTANCE_ERROR){
549 char errBuf[256];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000550 sprintf(errBuf,
551 "DLL load failed with error code %d", hDLL);
552 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossumdadc8241996-05-23 22:51:40 +0000553 return NULL;
554 }
555 p = GetProcAddress(hDLL, funcname);
556 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000557#endif /* MS_WIN16 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000558
559#if defined(PYOS_OS2)
560 {
561 APIRET rc;
562 HMODULE hDLL;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000563 char failreason[256];
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000564
565 rc = DosLoadModule(failreason,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000566 sizeof(failreason),
567 pathname,
568 &hDLL);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000569
570 if (rc != NO_ERROR) {
571 char errBuf[256];
572 sprintf(errBuf,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000573 "DLL load failed, rc = %d, problem '%s': %s",
574 rc, failreason);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000575 PyErr_SetString(PyExc_ImportError, errBuf);
576 return NULL;
577 }
578
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000579 rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
580 if (rc != NO_ERROR)
581 p = NULL; /* Signify Failure to Acquire Entrypoint */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000582 }
583#endif /* PYOS_OS2 */
584
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000585#ifdef USE_DL
Guido van Rossum79f25d91997-04-29 20:08:16 +0000586 p = dl_loadmod(Py_GetProgramName(), pathname, funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000587#endif /* USE_DL */
588#ifdef USE_RLD
589 {
590 NXStream *errorStream;
591 struct mach_header *new_header;
592 const char *filenames[2];
593 long ret;
594 unsigned long ptr;
595
596 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
597 filenames[0] = pathname;
598 filenames[1] = NULL;
Guido van Rossumab076fd1998-08-24 14:15:44 +0000599
600#if HANDLE_OBJC_MODULES
601
602/* The following very bogus line of code ensures that
603 objc_msgSend, etc are linked into the binary. Without
604 it, dynamic loading of a module that includes objective-c
605 method calls will fail with "undefined symbol _objc_msgSend()".
606 This remains true even in the presence of the -ObjC flag
607 to the compiler
608*/
609
610 [Object name];
611
612/* objc_loadModules() dynamically loads the object files
613 indicated by the paths in filenames. If there are any
614 errors generated during loading -- typically due to the
615 inability to find particular symbols -- an error message
616 will be written to errorStream.
617 It returns 0 if the module is successfully loaded, 1
618 otherwise.
619*/
620
621 ret = !objc_loadModules(filenames, errorStream,
622 NULL, &new_header, NULL);
623
624#else /* !HANDLE_OBJC_MODULES */
625
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000626 ret = rld_load(errorStream, &new_header,
627 filenames, NULL);
628
Guido van Rossumab076fd1998-08-24 14:15:44 +0000629#endif /* HANDLE_OBJC_MODULES */
630
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000631 /* extract the error messages for the exception */
632 if(!ret) {
633 char *streamBuf;
634 int len, maxLen;
635
636 NXPutc(errorStream, (char)0);
637
638 NXGetMemoryBuffer(errorStream,
639 &streamBuf, &len, &maxLen);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000640 PyErr_SetString(PyExc_ImportError, streamBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000641 }
642
643 if(ret && rld_lookup(errorStream, funcname, &ptr))
644 p = (dl_funcptr) ptr;
645
646 NXCloseMemory(errorStream, NX_FREEBUFFER);
647
648 if(!ret)
649 return NULL;
650 }
651#endif /* USE_RLD */
652#ifdef hpux
653 {
654 shl_t lib;
655 int flags;
656
Guido van Rossum3afb5951996-12-05 23:15:35 +0000657 flags = BIND_FIRST | BIND_DEFERRED;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000658 if (Py_VerboseFlag) {
659 flags = DYNAMIC_PATH | BIND_FIRST | BIND_IMMEDIATE |
Guido van Rossum79f25d91997-04-29 20:08:16 +0000660 BIND_NONFATAL | BIND_VERBOSE;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000661 printf("shl_load %s\n",pathname);
662 }
663 lib = shl_load(pathname, flags, 0);
664 /* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
665 if (lib == NULL) {
666 char buf[256];
667 if (Py_VerboseFlag)
668 perror(pathname);
669 sprintf(buf, "Failed to load %.200s", pathname);
670 PyErr_SetString(PyExc_ImportError, buf);
671 return NULL;
672 }
673 if (Py_VerboseFlag)
674 printf("shl_findsym %s\n", funcname);
675 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
676 if (p == NULL && Py_VerboseFlag)
677 perror(funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000678 }
679#endif /* hpux */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000680#ifdef __BEOS__
681 {
682 image_id the_id;
683 status_t retval;
684 char fullpath[PATH_MAX];
685
686 if( Py_VerboseFlag ) {
687 printf( "load_add_on( %s )\n", pathname );
688 }
689
690 /* Hmm, this old bug appears to have regenerated itself; if the
691 * path isn't absolute, load_add_on() will fail. Reported to Be
692 * April 21, 1998.
693 */
694 if( pathname[0] != '/' ) {
695 (void)getcwd( fullpath, PATH_MAX );
696 (void)strncat( fullpath, "/", PATH_MAX );
697 (void)strncat( fullpath, pathname, PATH_MAX );
698
699 if( Py_VerboseFlag ) {
700 printf( "load_add_on( %s )\n", fullpath );
701 }
702 } else {
703 (void)strcpy( fullpath, pathname );
704 }
705
706 the_id = load_add_on( fullpath );
707 if( the_id < B_NO_ERROR ) {
708 /* It's too bad load_add_on() doesn't set errno or something...
709 */
710 char buff[256]; /* hate hard-coded string sizes... */
711
712 if( Py_VerboseFlag ) {
713 printf( "load_add_on( %s ) failed", fullpath );
714 }
715
716 switch( the_id ) {
717 case B_ERROR:
718 sprintf( buff, "BeOS: Failed to load %.200s", fullpath );
719 break;
720 default:
721 sprintf( buff, "Unknown error loading %.200s", fullpath );
722 break;
723 }
724
725 PyErr_SetString( PyExc_ImportError, buff );
726 return NULL;
727 }
728
729 if( Py_VerboseFlag ) {
730 printf( "get_image_symbol( %s )\n", funcname );
731 }
732
733 retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
734 if( retval != B_NO_ERROR || p == NULL ) {
735 /* That's bad, we can't find that symbol in the module...
736 */
737 char buff[256]; /* hate hard-coded string sizes... */
738
739 if( Py_VerboseFlag ) {
740 printf( "get_image_symbol( %s ) failed", funcname );
741 }
742
743 switch( retval ) {
744 case B_BAD_IMAGE_ID:
745 sprintf( buff, "can't load init function for dynamic module: "
746 "Invalid image ID for %.180s", fullpath );
747 break;
748 case B_BAD_INDEX:
749 sprintf( buff, "can't load init function for dynamic module: "
750 "Bad index for %.180s", funcname );
751 break;
752 default:
753 sprintf( buff, "can't load init function for dynamic module: "
754 "Unknown error looking up %.180s", funcname );
755 break;
756 }
757
758 retval = unload_add_on( the_id );
759
760 PyErr_SetString( PyExc_ImportError, buff );
761 return NULL;
762 }
763
764 /* Save the module name and image ID for later so we can clean up
765 * gracefully.
766 */
767 beos_add_dyn( name, the_id );
768 }
769#endif /* __BEOS__ */
Guido van Rossum644a12b1997-04-09 19:24:53 +0000770#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000771 got_it:
Guido van Rossum644a12b1997-04-09 19:24:53 +0000772#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000773 if (p == NULL) {
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000774 PyErr_Format(PyExc_ImportError,
Guido van Rossum42e8e5d1998-01-19 22:23:08 +0000775 "dynamic module does not define init function (%.200s)",
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000776 funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000777 return NULL;
778 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000779 _Py_PackageContext = packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000780 (*p)();
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000781 _Py_PackageContext = NULL;
Guido van Rossum25ce5661997-08-02 03:10:38 +0000782 if (PyErr_Occurred())
783 return NULL;
784 if (_PyImport_FixupExtension(name, pathname) == NULL)
785 return NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000786
Guido van Rossumef3d02e1997-07-21 14:54:36 +0000787 m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000788 if (m == NULL) {
Guido van Rossum25ce5661997-08-02 03:10:38 +0000789 PyErr_SetString(PyExc_SystemError,
790 "dynamic module not initialized properly");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000791 return NULL;
792 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000793 /* Remember the filename as the __file__ attribute */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000794 d = PyModule_GetDict(m);
795 s = PyString_FromString(pathname);
796 if (s == NULL || PyDict_SetItemString(d, "__file__", s) != 0)
797 PyErr_Clear(); /* Not important enough to report */
798 Py_XDECREF(s);
799 if (Py_VerboseFlag)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000800 fprintf(stderr,
801 "import %s # dynamically loaded from %s\n",
802 name, pathname);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000803 Py_INCREF(m);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000804 return m;
805#endif /* DYNAMIC_LINK */
806}
807
808
809#ifdef _AIX
810
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000811#include <ctype.h> /* for isdigit() */
812#include <errno.h> /* for global errno */
813#include <string.h> /* for strerror() */
814#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000815
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000816typedef struct Module {
817 struct Module *next;
818 void *entry;
819} Module, *ModulePtr;
820
821static int
822aix_getoldmodules(modlistptr)
823 void **modlistptr;
824{
825 register ModulePtr modptr, prevmodptr;
826 register struct ld_info *ldiptr;
827 register char *ldibuf;
828 register int errflag, bufsize = 1024;
829 register unsigned int offset;
830
831 /*
832 -- Get the list of loaded modules into ld_info structures.
833 */
834 if ((ldibuf = malloc(bufsize)) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000835 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000836 return -1;
837 }
838 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
839 && errno == ENOMEM) {
840 free(ldibuf);
841 bufsize += 1024;
842 if ((ldibuf = malloc(bufsize)) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000843 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000844 return -1;
845 }
846 }
847 if (errflag == -1) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000848 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000849 return -1;
850 }
851 /*
852 -- Make the modules list from the ld_info structures.
853 */
854 ldiptr = (struct ld_info *)ldibuf;
855 prevmodptr = NULL;
856 do {
Guido van Rossum3b31cd21997-10-10 17:40:00 +0000857 if (strstr(ldiptr->ldinfo_filename, "python") == NULL) {
858 /*
859 -- Extract only the modules containing "python" as a
860 -- substring, like the "python[version]" executable or
861 -- "libpython[version].a" in case python is embedded.
862 */
863 offset = (unsigned int)ldiptr->ldinfo_next;
864 ldiptr = (struct ld_info *)((unsigned int)
865 ldiptr + offset);
866 continue;
867 }
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000868 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000869 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000870 while (*modlistptr) {
871 modptr = (ModulePtr)*modlistptr;
872 *modlistptr = (void *)modptr->next;
873 free(modptr);
874 }
875 return -1;
876 }
877 modptr->entry = ldiptr->ldinfo_dataorg;
878 modptr->next = NULL;
879 if (prevmodptr == NULL)
880 *modlistptr = (void *)modptr;
881 else
882 prevmodptr->next = modptr;
883 prevmodptr = modptr;
884 offset = (unsigned int)ldiptr->ldinfo_next;
885 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
886 } while (offset);
887 free(ldibuf);
888 return 0;
889}
890
891static int
892aix_bindnewmodule(newmoduleptr, modlistptr)
893 void *newmoduleptr;
894 void *modlistptr;
895{
896 register ModulePtr modptr;
897
898 /*
899 -- Bind the new module with the list of loaded modules.
900 */
901 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
902 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
903 return -1;
904 return 0;
905}
906
907static void
908aix_loaderror(pathname)
909 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000910{
911
Guido van Rossum236f62d1996-06-26 21:07:08 +0000912 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000913 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000914
915 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000916 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000917 char *errstr;
918 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000919 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000920 {L_ERROR_NOLIB, "can't load library:"},
921 {L_ERROR_UNDEF, "can't find symbol in library:"},
922 {L_ERROR_RLDBAD,
923 "RLD index out of range or bad relocation type:"},
924 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
925 {L_ERROR_MEMBER,
926 "file not an archive or does not contain requested member:"},
927 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000928 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000929 {L_ERROR_SYSTEM, "System error:"},
930 {L_ERROR_ERRNO, NULL}
931 };
932
933#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
934#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
935
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000936 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000937
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000938 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000939 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000940 ERRBUF_APPEND("\n");
941 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000942 for(i = 0; message[i] && *message[i]; i++) {
943 int nerr = atoi(message[i]);
944 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000945 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000946 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000947 }
948 while (isdigit(*message[i])) message[i]++ ;
949 ERRBUF_APPEND(message[i]);
950 ERRBUF_APPEND("\n");
951 }
952 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000953 PyErr_SetString(PyExc_ImportError, errbuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000954 return;
955}
956
957#endif /* _AIX */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000958
959#ifdef __BEOS__
960/* ----------------------------------------------------------------------
961 * BeOS dynamic loading support
962 *
963 * This uses shared libraries, but BeOS has its own way of doing things
964 * (much easier than dlfnc.h, from the look of things). We'll use a
965 * Python Dictionary object to store the images_ids so we can be very
966 * nice and unload them when we exit.
967 *
968 * Note that this is thread-safe. Probably irrelevent, because of losing
969 * systems... Python probably disables threads while loading modules.
970 * Note the use of "probably"! Better to be safe than sorry. [chrish]
971 *
972 * As of 1.5.1 this should also work properly when you've configured
973 * Python without thread support; the 1.5 version required it, which wasn't
974 * very friendly. Note that I haven't tested it without threading... why
975 * would you want to avoid threads on BeOS? [chrish]
976 */
977
978/*
979 * Initialize our dictionary, and the dictionary mutex.
980 */
981static void beos_init_dyn( void )
982{
983 /* We're protected from a race condition here by the atomic init_count
984 * variable.
985 */
986 static int32 init_count = 0;
987 int32 val;
988
989 val = atomic_add( &init_count, 1 );
990 if( beos_dyn_images == NULL && val == 0 ) {
991 beos_dyn_images = PyDict_New();
992#ifdef WITH_THREAD
993 beos_dyn_lock = PyThread_allocate_lock();
994#endif
995 atexit( beos_cleanup_dyn );
996 }
997}
998
999/* atexit() handler that'll call unload_add_on() for every item in the
1000 * dictionary.
1001 */
1002static void beos_cleanup_dyn( void )
1003{
1004 if( beos_dyn_images ) {
1005 int idx;
1006 int list_size;
1007 PyObject *id_list;
1008
1009#ifdef WITH_THREAD
1010 PyThread_acquire_lock( beos_dyn_lock, 1 );
1011#endif
1012
1013 id_list = PyDict_Values( beos_dyn_images );
1014
1015 list_size = PyList_Size( id_list );
1016 for( idx = 0; idx < list_size; idx++ ) {
1017 PyObject *the_item;
1018
1019 the_item = PyList_GetItem( id_list, idx );
1020 beos_nuke_dyn( the_item );
1021 }
1022
1023 PyDict_Clear( beos_dyn_images );
1024
1025#ifdef WITH_THREAD
1026 PyThread_free_lock( beos_dyn_lock );
1027#endif
1028 }
1029}
1030
1031/* Whack an item; the item is an image_id in disguise, so we'll call
1032 * unload_add_on() for it.
1033 */
1034static void beos_nuke_dyn( PyObject *item )
1035{
1036 status_t retval;
1037
1038 if( item ) {
1039 image_id id = (image_id)PyInt_AsLong( item );
1040
1041 retval = unload_add_on( id );
1042 }
1043}
1044
1045/*
1046 * Add an image_id to the dictionary; the module name of the loaded image
1047 * is the key. Note that if the key is already in the dict, we unload
1048 * that image; this should allow reload() to work on dynamically loaded
1049 * modules (super-keen!).
1050 */
1051static void beos_add_dyn( char *name, image_id id )
1052{
1053 int retval;
1054 PyObject *py_id;
1055
1056 if( beos_dyn_images == NULL ) {
1057 beos_init_dyn();
1058 }
1059
1060#ifdef WITH_THREAD
1061 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1062#endif
1063
1064 /* If there's already an object with this key in the dictionary,
1065 * we're doing a reload(), so let's nuke it.
1066 */
1067 py_id = PyDict_GetItemString( beos_dyn_images, name );
1068 if( py_id ) {
1069 beos_nuke_dyn( py_id );
1070 retval = PyDict_DelItemString( beos_dyn_images, name );
1071 }
1072
1073 py_id = PyInt_FromLong( (long)id );
1074 if( py_id ) {
1075 retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
1076 }
1077
1078#ifdef WITH_THREAD
1079 PyThread_release_lock( beos_dyn_lock );
1080#endif
1081}
1082
1083/* Given a module name, return the image_id (if it's a dynamically loaded
1084 * module). [Donn Cave]
1085 */
1086image_id PyImport_BeImageID( char *name )
1087{
1088 int retval;
1089 PyObject *py_id;
1090 long id;
1091
1092 if( !beos_dyn_images ) {
1093 return B_ERROR;
1094 }
1095
1096#ifdef WITH_THREAD
1097 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1098#endif
1099
1100 py_id = PyDict_GetItemString( beos_dyn_images, name );
1101 if( py_id ) {
1102 id = PyInt_AsLong( py_id );
1103 } else {
1104 id = B_ERROR;
1105 }
1106
1107#ifdef WITH_THREAD
1108 PyThread_release_lock( beos_dyn_lock );
1109#endif
1110
1111 return (image_id)id;
1112}
1113#endif /* __BEOS__ */