blob: 2947d1586fed9fdd39e1951488a435a0c74c44ef [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 Rossum54dec591997-08-16 14:38:09 +0000123#define SHORT_EXT ".so"
124#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000125#endif
126
127#ifdef WITH_SGI_DL
128#define DYNAMIC_LINK
129#define USE_DL
130#endif
131
132#ifdef WITH_DL_DLD
133#define DYNAMIC_LINK
134#define USE_DL
135#endif
136
Jack Jansen5d9acb61995-06-14 14:54:25 +0000137#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen4e043731995-02-13 22:42:34 +0000138#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000139#define SHORT_EXT ".slb"
Guido van Rossum1e612491996-08-19 22:12:10 +0000140#ifdef __CFM68K__
141#define LONG_EXT ".CFM68K.slb"
142#else
143#define LONG_EXT ".ppc.slb"
144#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000145#ifndef _DL_FUNCPTR_DEFINED
146typedef void (*dl_funcptr)();
147#endif
148#endif
149
Guido van Rossum504f4a91996-08-20 19:59:07 +0000150#if !defined(DYNAMIC_LINK) && (defined(HAVE_DLOPEN) || defined(M_UNIX))
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000151#define DYNAMIC_LINK
152#define USE_SHLIB
153#endif
154
155#ifdef _AIX
Guido van Rossumef3d02e1997-07-21 14:54:36 +0000156#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 +0000157#define DYNAMIC_LINK
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000158#define SHORT_EXT ".so"
159#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000160#include <sys/ldr.h>
161typedef void (*dl_funcptr)();
162#define _DL_FUNCPTR_DEFINED
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000163static int aix_getoldmodules(void **);
164static int aix_bindnewmodule(void *, void *);
165static void aix_loaderror(char *);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000166#endif
167
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000168#ifdef __BEOS__
169# undef USE_SHLIB /* probably not defined anyway */
170# define DYNAMIC_LINK
171# define SHORT_EXT ".so"
172# define LONG_EXT "module.so"
173typedef void (*dl_funcptr)(void);
174# define _DL_FUNCPTR_DEFINED
175
176# if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
177# undef MAXPATHLEN
178# endif
179
180# include <kernel/image.h>
181# include <kernel/OS.h>
182# include <stdlib.h>
183# include <unistd.h>
184
185# ifdef WITH_THREAD
186# include "thread.h"
187static type_lock beos_dyn_lock;
188# endif
189
190static PyObject *beos_dyn_images = NULL;
191
192static void beos_init_dyn( void );
193static void beos_cleanup_dyn( void );
194static void beos_nuke_dyn( PyObject *item );
195static void beos_add_dyn( char *pathname, image_id id );
196
197/* External interface for finding image IDs; useful if you need to
198 * do your own symbol lookup in dynamically loaded modules. [Donn Cave]
199 *
200 * Hmm, could we hack up the Sun dlmodule instead for this sort of thing?
201 * That might be more generally useful. [chrish]
202 */
203image_id PyImport_BeImageID( char *name );
204#endif
205
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000206#ifdef DYNAMIC_LINK
207
208#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000209#include <sys/types.h>
210#include <sys/stat.h>
Guido van Rossum15af20a1998-01-19 22:03:52 +0000211#if defined(__NetBSD__) && (NetBSD < 199712)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000212#include <nlist.h>
213#include <link.h>
214#else
Guido van Rossum504f4a91996-08-20 19:59:07 +0000215#ifdef HAVE_DLFCN_H
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000216#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000217#endif
Guido van Rossum504f4a91996-08-20 19:59:07 +0000218#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000219#ifndef _DL_FUNCPTR_DEFINED
220typedef void (*dl_funcptr)();
221#endif
222#ifndef RTLD_LAZY
223#define RTLD_LAZY 1
224#endif
225#define SHORT_EXT ".so"
226#define LONG_EXT "module.so"
227#endif /* USE_SHLIB */
228
229#if defined(USE_DL) || defined(hpux)
230#include "dl.h"
231#endif
232
Jack Jansen5d9acb61995-06-14 14:54:25 +0000233#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000234#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000235#include <CodeFragments.h>
Guido van Rossum79f25d91997-04-29 20:08:16 +0000236#ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000237#define CFragConnectionID ConnectionID
238#define kLoadCFrag 0x01
239#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000240#include <Files.h>
241#include "macdefs.h"
242#include "macglue.h"
243#endif
244
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000245#ifdef USE_RLD
246#include <mach-o/rld.h>
247#define FUNCNAME_PATTERN "_init%.200s"
248#ifndef _DL_FUNCPTR_DEFINED
249typedef void (*dl_funcptr)();
250#endif
251#endif /* USE_RLD */
252
Guido van Rossum79f25d91997-04-29 20:08:16 +0000253extern char *Py_GetProgramName();
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000254
255#ifndef FUNCNAME_PATTERN
Guido van Rossum1f740161998-04-13 15:27:21 +0000256#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000257#define FUNCNAME_PATTERN "_init%.200s"
258#else
259#define FUNCNAME_PATTERN "init%.200s"
260#endif
261#endif
262
263#if !defined(SHORT_EXT) && !defined(LONG_EXT)
264#define SHORT_EXT ".o"
265#define LONG_EXT "module.o"
266#endif /* !SHORT_EXT && !LONG_EXT */
267
268#endif /* DYNAMIC_LINK */
269
Guido van Rossum79f25d91997-04-29 20:08:16 +0000270struct filedescr _PyImport_Filetab[] = {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000271#ifdef SHORT_EXT
272 {SHORT_EXT, "rb", C_EXTENSION},
273#endif /* !SHORT_EXT */
274#ifdef LONG_EXT
275 {LONG_EXT, "rb", C_EXTENSION},
276#endif /* !LONG_EXT */
277 {".py", "r", PY_SOURCE},
278 {".pyc", "rb", PY_COMPILED},
279 {0, 0}
280};
281
Guido van Rossum38234201996-07-31 17:55:19 +0000282#ifdef NO_DYNAMIC_LINK
283#undef DYNAMIC_LINK
284#endif
285
Guido van Rossum79f25d91997-04-29 20:08:16 +0000286PyObject *
287_PyImport_LoadDynamicModule(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000288 char *name;
289 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000290 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000291{
292#ifndef DYNAMIC_LINK
Guido van Rossum79f25d91997-04-29 20:08:16 +0000293 PyErr_SetString(PyExc_ImportError,
294 "dynamically linked modules not supported");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000295 return NULL;
296#else
Guido van Rossum79f25d91997-04-29 20:08:16 +0000297 PyObject *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000298 char funcname[258];
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000299 char *lastdot, *shortname, *packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000300 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000301#ifdef USE_SHLIB
302 static struct {
303 dev_t dev;
304 ino_t ino;
305 void *handle;
306 } handles[128];
307 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000308 char pathbuf[260];
309 if (strchr(pathname, '/') == NULL) {
310 /* Prefix bare filename with "./" */
311 sprintf(pathbuf, "./%-.255s", pathname);
312 pathname = pathbuf;
313 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000314#endif
Guido van Rossum25ce5661997-08-02 03:10:38 +0000315 if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
316 Py_INCREF(m);
317 return m;
318 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000319 lastdot = strrchr(name, '.');
320 if (lastdot == NULL) {
321 packagecontext = NULL;
322 shortname = name;
323 }
324 else {
325 packagecontext = name;
326 shortname = lastdot+1;
327 }
328 sprintf(funcname, FUNCNAME_PATTERN, shortname);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000329#ifdef USE_SHLIB
330 if (fp != NULL) {
331 int i;
332 struct stat statb;
333 fstat(fileno(fp), &statb);
334 for (i = 0; i < nhandles; i++) {
335 if (statb.st_dev == handles[i].dev &&
336 statb.st_ino == handles[i].ino) {
337 p = (dl_funcptr) dlsym(handles[i].handle,
338 funcname);
339 goto got_it;
340 }
341 }
342 if (nhandles < 128) {
343 handles[nhandles].dev = statb.st_dev;
344 handles[nhandles].ino = statb.st_ino;
345 }
346 }
347#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000348#ifdef USE_MAC_DYNAMIC_LOADING
349 /*
Guido van Rossum79f25d91997-04-29 20:08:16 +0000350 ** Dynamic loading of CFM shared libraries on the Mac. The
351 ** code has become more convoluted than it was, because we
352 ** want to be able to put multiple modules in a single
353 ** file. For this reason, we have to determine the fragment
354 ** name, and we cannot use the library entry point but we have
355 ** to locate the correct init routine "by hand".
Jack Jansen5d9acb61995-06-14 14:54:25 +0000356 */
Jack Jansen4e043731995-02-13 22:42:34 +0000357 {
358 FSSpec libspec;
359 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000360 Ptr mainAddr;
361 Str255 errMessage;
362 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000363 Boolean isfolder, didsomething;
364 char buf[512];
365 Str63 fragname;
366 Ptr symAddr;
367 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000368
Jack Jansen5d9acb61995-06-14 14:54:25 +0000369 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000370 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000371 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
372 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000373 sprintf(buf, "%.255s: %.200s",
374 pathname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000375 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000376 return NULL;
377 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000378 /* Next, determine the fragment name,
379 by stripping '.slb' and 'module' */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000380 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
381 fragname[0] = libspec.name[0];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000382 if( strncmp((char *)(fragname+1+fragname[0]-4),
383 ".slb", 4) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000384 fragname[0] -= 4;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000385 if ( strncmp((char *)(fragname+1+fragname[0]-6),
386 "module", 6) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000387 fragname[0] -= 6;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000388 /* Load the fragment
389 (or return the connID if it is already loaded */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000390 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000391 kLoadCFrag, &connID, &mainAddr,
392 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000393 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000394 sprintf(buf, "%.*s: %.200s",
395 errMessage[0], errMessage+1,
Guido van Rossum79f25d91997-04-29 20:08:16 +0000396 PyMac_StrError(err));
397 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen4e043731995-02-13 22:42:34 +0000398 return NULL;
399 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000400 /* Locate the address of the correct init function */
401 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
402 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000403 sprintf(buf, "%s: %.200s",
404 funcname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000405 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000406 return NULL;
407 }
408 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000409 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000410#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000411#ifdef USE_SHLIB
412 {
413#ifdef RTLD_NOW
414 /* RTLD_NOW: resolve externals now
415 (i.e. core dump now if some are missing) */
Guido van Rossum6b077871998-05-18 13:42:45 +0000416 void *handle = dlopen(pathname, RTLD_NOW);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000417#else
418 void *handle;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000419 if (Py_VerboseFlag)
Guido van Rossum08052c71997-12-02 20:43:18 +0000420 printf("dlopen(\"%s\", %d);\n", pathname,
Guido van Rossum6b077871998-05-18 13:42:45 +0000421 RTLD_LAZY);
422 handle = dlopen(pathname, RTLD_LAZY);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000423#endif /* RTLD_NOW */
424 if (handle == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000425 PyErr_SetString(PyExc_ImportError, dlerror());
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000426 return NULL;
427 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000428 if (fp != NULL && nhandles < 128)
429 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000430 p = (dl_funcptr) dlsym(handle, funcname);
431 }
432#endif /* USE_SHLIB */
433#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000434 /*
435 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
436 -- of the shared module unresolved. Thus we have to resolve them
437 -- explicitely with loadbind. The new module is loaded, then we
438 -- resolve its symbols using the list of already loaded modules
439 -- (only those that belong to the python executable). Get these
440 -- with loadquery(L_GETINFO).
441 */
442 {
443 static void *staticmodlistptr = NULL;
444
445 if (!staticmodlistptr)
446 if (aix_getoldmodules(&staticmodlistptr) == -1)
447 return NULL;
448 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
449 if (p == NULL) {
450 aix_loaderror(pathname);
451 return NULL;
452 }
453 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
454 aix_loaderror(pathname);
455 return NULL;
456 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000457 }
458#endif /* _AIX */
Guido van Rossum9b38a141996-09-11 23:12:24 +0000459#ifdef MS_WIN32
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000460 {
461 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000462 char pathbuf[260];
463 if (strchr(pathname, SEP) == NULL &&
464 strchr(pathname, ALTSEP) == NULL)
465 {
466 /* Prefix bare filename with ".\" */
467 char *p = pathbuf;
468 *p = '\0';
469 _getcwd(pathbuf, sizeof pathbuf);
470 if (*p != '\0' && p[1] == ':')
471 p += 2;
472 sprintf(p, ".\\%-.255s", pathname);
473 pathname = pathbuf;
474 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000475 hDLL = LoadLibrary(pathname);
476 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000477 char errBuf[256];
478 unsigned int errorCode;
479
480 /* Get an error string from Win32 error code */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000481 char theInfo[256]; /* Pointer to error text
482 from system */
483 int theLength; /* Length of error text */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000484
485 errorCode = GetLastError();
486
Guido van Rossum79f25d91997-04-29 20:08:16 +0000487 theLength = FormatMessage(
488 FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
489 NULL, /* message source */
490 errorCode, /* the message (error) ID */
491 0, /* default language environment */
492 (LPTSTR) theInfo, /* the buffer */
493 sizeof(theInfo), /* the buffer size */
494 NULL); /* no additional format args. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000495
Guido van Rossum79f25d91997-04-29 20:08:16 +0000496 /* Problem: could not get the error message.
497 This should not happen if called correctly. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000498 if (theLength == 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000499 sprintf(errBuf,
500 "DLL load failed with error code %d",
501 errorCode);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000502 } else {
503 int len;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000504 /* For some reason a \r\n
505 is appended to the text */
506 if (theLength >= 2 &&
507 theInfo[theLength-2] == '\r' &&
508 theInfo[theLength-1] == '\n') {
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000509 theLength -= 2;
510 theInfo[theLength] = '\0';
511 }
512 strcpy(errBuf, "DLL load failed: ");
513 len = strlen(errBuf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000514 strncpy(errBuf+len, theInfo,
515 sizeof(errBuf)-len);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000516 errBuf[sizeof(errBuf)-1] = '\0';
517 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000518 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000519 return NULL;
520 }
521 p = GetProcAddress(hDLL, funcname);
522 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000523#endif /* MS_WIN32 */
524#ifdef MS_WIN16
Guido van Rossumdadc8241996-05-23 22:51:40 +0000525 {
526 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000527 char pathbuf[16];
528 if (strchr(pathname, SEP) == NULL &&
529 strchr(pathname, ALTSEP) == NULL)
530 {
531 /* Prefix bare filename with ".\" */
532 sprintf(pathbuf, ".\\%-.13s", pathname);
533 pathname = pathbuf;
534 }
Guido van Rossumdadc8241996-05-23 22:51:40 +0000535 hDLL = LoadLibrary(pathname);
536 if (hDLL < HINSTANCE_ERROR){
537 char errBuf[256];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000538 sprintf(errBuf,
539 "DLL load failed with error code %d", hDLL);
540 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossumdadc8241996-05-23 22:51:40 +0000541 return NULL;
542 }
543 p = GetProcAddress(hDLL, funcname);
544 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000545#endif /* MS_WIN16 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000546
547#if defined(PYOS_OS2)
548 {
549 APIRET rc;
550 HMODULE hDLL;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000551 char failreason[256];
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000552
553 rc = DosLoadModule(failreason,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000554 sizeof(failreason),
555 pathname,
556 &hDLL);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000557
558 if (rc != NO_ERROR) {
559 char errBuf[256];
560 sprintf(errBuf,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000561 "DLL load failed, rc = %d, problem '%s': %s",
562 rc, failreason);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000563 PyErr_SetString(PyExc_ImportError, errBuf);
564 return NULL;
565 }
566
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000567 rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
568 if (rc != NO_ERROR)
569 p = NULL; /* Signify Failure to Acquire Entrypoint */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000570 }
571#endif /* PYOS_OS2 */
572
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000573#ifdef USE_DL
Guido van Rossum79f25d91997-04-29 20:08:16 +0000574 p = dl_loadmod(Py_GetProgramName(), pathname, funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000575#endif /* USE_DL */
576#ifdef USE_RLD
577 {
578 NXStream *errorStream;
579 struct mach_header *new_header;
580 const char *filenames[2];
581 long ret;
582 unsigned long ptr;
583
584 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
585 filenames[0] = pathname;
586 filenames[1] = NULL;
587 ret = rld_load(errorStream, &new_header,
588 filenames, NULL);
589
590 /* extract the error messages for the exception */
591 if(!ret) {
592 char *streamBuf;
593 int len, maxLen;
594
595 NXPutc(errorStream, (char)0);
596
597 NXGetMemoryBuffer(errorStream,
598 &streamBuf, &len, &maxLen);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000599 PyErr_SetString(PyExc_ImportError, streamBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000600 }
601
602 if(ret && rld_lookup(errorStream, funcname, &ptr))
603 p = (dl_funcptr) ptr;
604
605 NXCloseMemory(errorStream, NX_FREEBUFFER);
606
607 if(!ret)
608 return NULL;
609 }
610#endif /* USE_RLD */
611#ifdef hpux
612 {
613 shl_t lib;
614 int flags;
615
Guido van Rossum3afb5951996-12-05 23:15:35 +0000616 flags = BIND_FIRST | BIND_DEFERRED;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000617 if (Py_VerboseFlag) {
618 flags = DYNAMIC_PATH | BIND_FIRST | BIND_IMMEDIATE |
Guido van Rossum79f25d91997-04-29 20:08:16 +0000619 BIND_NONFATAL | BIND_VERBOSE;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000620 printf("shl_load %s\n",pathname);
621 }
622 lib = shl_load(pathname, flags, 0);
623 /* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
624 if (lib == NULL) {
625 char buf[256];
626 if (Py_VerboseFlag)
627 perror(pathname);
628 sprintf(buf, "Failed to load %.200s", pathname);
629 PyErr_SetString(PyExc_ImportError, buf);
630 return NULL;
631 }
632 if (Py_VerboseFlag)
633 printf("shl_findsym %s\n", funcname);
634 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
635 if (p == NULL && Py_VerboseFlag)
636 perror(funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000637 }
638#endif /* hpux */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000639#ifdef __BEOS__
640 {
641 image_id the_id;
642 status_t retval;
643 char fullpath[PATH_MAX];
644
645 if( Py_VerboseFlag ) {
646 printf( "load_add_on( %s )\n", pathname );
647 }
648
649 /* Hmm, this old bug appears to have regenerated itself; if the
650 * path isn't absolute, load_add_on() will fail. Reported to Be
651 * April 21, 1998.
652 */
653 if( pathname[0] != '/' ) {
654 (void)getcwd( fullpath, PATH_MAX );
655 (void)strncat( fullpath, "/", PATH_MAX );
656 (void)strncat( fullpath, pathname, PATH_MAX );
657
658 if( Py_VerboseFlag ) {
659 printf( "load_add_on( %s )\n", fullpath );
660 }
661 } else {
662 (void)strcpy( fullpath, pathname );
663 }
664
665 the_id = load_add_on( fullpath );
666 if( the_id < B_NO_ERROR ) {
667 /* It's too bad load_add_on() doesn't set errno or something...
668 */
669 char buff[256]; /* hate hard-coded string sizes... */
670
671 if( Py_VerboseFlag ) {
672 printf( "load_add_on( %s ) failed", fullpath );
673 }
674
675 switch( the_id ) {
676 case B_ERROR:
677 sprintf( buff, "BeOS: Failed to load %.200s", fullpath );
678 break;
679 default:
680 sprintf( buff, "Unknown error loading %.200s", fullpath );
681 break;
682 }
683
684 PyErr_SetString( PyExc_ImportError, buff );
685 return NULL;
686 }
687
688 if( Py_VerboseFlag ) {
689 printf( "get_image_symbol( %s )\n", funcname );
690 }
691
692 retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
693 if( retval != B_NO_ERROR || p == NULL ) {
694 /* That's bad, we can't find that symbol in the module...
695 */
696 char buff[256]; /* hate hard-coded string sizes... */
697
698 if( Py_VerboseFlag ) {
699 printf( "get_image_symbol( %s ) failed", funcname );
700 }
701
702 switch( retval ) {
703 case B_BAD_IMAGE_ID:
704 sprintf( buff, "can't load init function for dynamic module: "
705 "Invalid image ID for %.180s", fullpath );
706 break;
707 case B_BAD_INDEX:
708 sprintf( buff, "can't load init function for dynamic module: "
709 "Bad index for %.180s", funcname );
710 break;
711 default:
712 sprintf( buff, "can't load init function for dynamic module: "
713 "Unknown error looking up %.180s", funcname );
714 break;
715 }
716
717 retval = unload_add_on( the_id );
718
719 PyErr_SetString( PyExc_ImportError, buff );
720 return NULL;
721 }
722
723 /* Save the module name and image ID for later so we can clean up
724 * gracefully.
725 */
726 beos_add_dyn( name, the_id );
727 }
728#endif /* __BEOS__ */
Guido van Rossum644a12b1997-04-09 19:24:53 +0000729#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000730 got_it:
Guido van Rossum644a12b1997-04-09 19:24:53 +0000731#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000732 if (p == NULL) {
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000733 PyErr_Format(PyExc_ImportError,
Guido van Rossum42e8e5d1998-01-19 22:23:08 +0000734 "dynamic module does not define init function (%.200s)",
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000735 funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000736 return NULL;
737 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000738 _Py_PackageContext = packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000739 (*p)();
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000740 _Py_PackageContext = NULL;
Guido van Rossum25ce5661997-08-02 03:10:38 +0000741 if (PyErr_Occurred())
742 return NULL;
743 if (_PyImport_FixupExtension(name, pathname) == NULL)
744 return NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000745
Guido van Rossumef3d02e1997-07-21 14:54:36 +0000746 m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000747 if (m == NULL) {
Guido van Rossum25ce5661997-08-02 03:10:38 +0000748 PyErr_SetString(PyExc_SystemError,
749 "dynamic module not initialized properly");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000750 return NULL;
751 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000752 /* Remember the filename as the __file__ attribute */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000753 d = PyModule_GetDict(m);
754 s = PyString_FromString(pathname);
755 if (s == NULL || PyDict_SetItemString(d, "__file__", s) != 0)
756 PyErr_Clear(); /* Not important enough to report */
757 Py_XDECREF(s);
758 if (Py_VerboseFlag)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000759 fprintf(stderr,
760 "import %s # dynamically loaded from %s\n",
761 name, pathname);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000762 Py_INCREF(m);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000763 return m;
764#endif /* DYNAMIC_LINK */
765}
766
767
768#ifdef _AIX
769
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000770#include <ctype.h> /* for isdigit() */
771#include <errno.h> /* for global errno */
772#include <string.h> /* for strerror() */
773#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000774
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000775typedef struct Module {
776 struct Module *next;
777 void *entry;
778} Module, *ModulePtr;
779
780static int
781aix_getoldmodules(modlistptr)
782 void **modlistptr;
783{
784 register ModulePtr modptr, prevmodptr;
785 register struct ld_info *ldiptr;
786 register char *ldibuf;
787 register int errflag, bufsize = 1024;
788 register unsigned int offset;
789
790 /*
791 -- Get the list of loaded modules into ld_info structures.
792 */
793 if ((ldibuf = malloc(bufsize)) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000794 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000795 return -1;
796 }
797 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
798 && errno == ENOMEM) {
799 free(ldibuf);
800 bufsize += 1024;
801 if ((ldibuf = malloc(bufsize)) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000802 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000803 return -1;
804 }
805 }
806 if (errflag == -1) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000807 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000808 return -1;
809 }
810 /*
811 -- Make the modules list from the ld_info structures.
812 */
813 ldiptr = (struct ld_info *)ldibuf;
814 prevmodptr = NULL;
815 do {
Guido van Rossum3b31cd21997-10-10 17:40:00 +0000816 if (strstr(ldiptr->ldinfo_filename, "python") == NULL) {
817 /*
818 -- Extract only the modules containing "python" as a
819 -- substring, like the "python[version]" executable or
820 -- "libpython[version].a" in case python is embedded.
821 */
822 offset = (unsigned int)ldiptr->ldinfo_next;
823 ldiptr = (struct ld_info *)((unsigned int)
824 ldiptr + offset);
825 continue;
826 }
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000827 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000828 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000829 while (*modlistptr) {
830 modptr = (ModulePtr)*modlistptr;
831 *modlistptr = (void *)modptr->next;
832 free(modptr);
833 }
834 return -1;
835 }
836 modptr->entry = ldiptr->ldinfo_dataorg;
837 modptr->next = NULL;
838 if (prevmodptr == NULL)
839 *modlistptr = (void *)modptr;
840 else
841 prevmodptr->next = modptr;
842 prevmodptr = modptr;
843 offset = (unsigned int)ldiptr->ldinfo_next;
844 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
845 } while (offset);
846 free(ldibuf);
847 return 0;
848}
849
850static int
851aix_bindnewmodule(newmoduleptr, modlistptr)
852 void *newmoduleptr;
853 void *modlistptr;
854{
855 register ModulePtr modptr;
856
857 /*
858 -- Bind the new module with the list of loaded modules.
859 */
860 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
861 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
862 return -1;
863 return 0;
864}
865
866static void
867aix_loaderror(pathname)
868 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000869{
870
Guido van Rossum236f62d1996-06-26 21:07:08 +0000871 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000872 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000873
874 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000875 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000876 char *errstr;
877 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000878 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000879 {L_ERROR_NOLIB, "can't load library:"},
880 {L_ERROR_UNDEF, "can't find symbol in library:"},
881 {L_ERROR_RLDBAD,
882 "RLD index out of range or bad relocation type:"},
883 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
884 {L_ERROR_MEMBER,
885 "file not an archive or does not contain requested member:"},
886 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000887 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000888 {L_ERROR_SYSTEM, "System error:"},
889 {L_ERROR_ERRNO, NULL}
890 };
891
892#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
893#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
894
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000895 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000896
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000897 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000898 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000899 ERRBUF_APPEND("\n");
900 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000901 for(i = 0; message[i] && *message[i]; i++) {
902 int nerr = atoi(message[i]);
903 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000904 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000905 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000906 }
907 while (isdigit(*message[i])) message[i]++ ;
908 ERRBUF_APPEND(message[i]);
909 ERRBUF_APPEND("\n");
910 }
911 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000912 PyErr_SetString(PyExc_ImportError, errbuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000913 return;
914}
915
916#endif /* _AIX */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000917
918#ifdef __BEOS__
919/* ----------------------------------------------------------------------
920 * BeOS dynamic loading support
921 *
922 * This uses shared libraries, but BeOS has its own way of doing things
923 * (much easier than dlfnc.h, from the look of things). We'll use a
924 * Python Dictionary object to store the images_ids so we can be very
925 * nice and unload them when we exit.
926 *
927 * Note that this is thread-safe. Probably irrelevent, because of losing
928 * systems... Python probably disables threads while loading modules.
929 * Note the use of "probably"! Better to be safe than sorry. [chrish]
930 *
931 * As of 1.5.1 this should also work properly when you've configured
932 * Python without thread support; the 1.5 version required it, which wasn't
933 * very friendly. Note that I haven't tested it without threading... why
934 * would you want to avoid threads on BeOS? [chrish]
935 */
936
937/*
938 * Initialize our dictionary, and the dictionary mutex.
939 */
940static void beos_init_dyn( void )
941{
942 /* We're protected from a race condition here by the atomic init_count
943 * variable.
944 */
945 static int32 init_count = 0;
946 int32 val;
947
948 val = atomic_add( &init_count, 1 );
949 if( beos_dyn_images == NULL && val == 0 ) {
950 beos_dyn_images = PyDict_New();
951#ifdef WITH_THREAD
952 beos_dyn_lock = PyThread_allocate_lock();
953#endif
954 atexit( beos_cleanup_dyn );
955 }
956}
957
958/* atexit() handler that'll call unload_add_on() for every item in the
959 * dictionary.
960 */
961static void beos_cleanup_dyn( void )
962{
963 if( beos_dyn_images ) {
964 int idx;
965 int list_size;
966 PyObject *id_list;
967
968#ifdef WITH_THREAD
969 PyThread_acquire_lock( beos_dyn_lock, 1 );
970#endif
971
972 id_list = PyDict_Values( beos_dyn_images );
973
974 list_size = PyList_Size( id_list );
975 for( idx = 0; idx < list_size; idx++ ) {
976 PyObject *the_item;
977
978 the_item = PyList_GetItem( id_list, idx );
979 beos_nuke_dyn( the_item );
980 }
981
982 PyDict_Clear( beos_dyn_images );
983
984#ifdef WITH_THREAD
985 PyThread_free_lock( beos_dyn_lock );
986#endif
987 }
988}
989
990/* Whack an item; the item is an image_id in disguise, so we'll call
991 * unload_add_on() for it.
992 */
993static void beos_nuke_dyn( PyObject *item )
994{
995 status_t retval;
996
997 if( item ) {
998 image_id id = (image_id)PyInt_AsLong( item );
999
1000 retval = unload_add_on( id );
1001 }
1002}
1003
1004/*
1005 * Add an image_id to the dictionary; the module name of the loaded image
1006 * is the key. Note that if the key is already in the dict, we unload
1007 * that image; this should allow reload() to work on dynamically loaded
1008 * modules (super-keen!).
1009 */
1010static void beos_add_dyn( char *name, image_id id )
1011{
1012 int retval;
1013 PyObject *py_id;
1014
1015 if( beos_dyn_images == NULL ) {
1016 beos_init_dyn();
1017 }
1018
1019#ifdef WITH_THREAD
1020 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1021#endif
1022
1023 /* If there's already an object with this key in the dictionary,
1024 * we're doing a reload(), so let's nuke it.
1025 */
1026 py_id = PyDict_GetItemString( beos_dyn_images, name );
1027 if( py_id ) {
1028 beos_nuke_dyn( py_id );
1029 retval = PyDict_DelItemString( beos_dyn_images, name );
1030 }
1031
1032 py_id = PyInt_FromLong( (long)id );
1033 if( py_id ) {
1034 retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
1035 }
1036
1037#ifdef WITH_THREAD
1038 PyThread_release_lock( beos_dyn_lock );
1039#endif
1040}
1041
1042/* Given a module name, return the image_id (if it's a dynamically loaded
1043 * module). [Donn Cave]
1044 */
1045image_id PyImport_BeImageID( char *name )
1046{
1047 int retval;
1048 PyObject *py_id;
1049 long id;
1050
1051 if( !beos_dyn_images ) {
1052 return B_ERROR;
1053 }
1054
1055#ifdef WITH_THREAD
1056 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1057#endif
1058
1059 py_id = PyDict_GetItemString( beos_dyn_images, name );
1060 if( py_id ) {
1061 id = PyInt_AsLong( py_id );
1062 } else {
1063 id = B_ERROR;
1064 }
1065
1066#ifdef WITH_THREAD
1067 PyThread_release_lock( beos_dyn_lock );
1068#endif
1069
1070 return (image_id)id;
1071}
1072#endif /* __BEOS__ */