blob: 7493e5800654b5352f0a16a8e09f3fd41ca863b8 [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 Rossum65d5b571998-12-21 19:32:43 +0000199static PyThread_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 );
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000208#endif
209
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000210#ifdef DYNAMIC_LINK
211
212#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000213#include <sys/types.h>
214#include <sys/stat.h>
Guido van Rossum15af20a1998-01-19 22:03:52 +0000215#if defined(__NetBSD__) && (NetBSD < 199712)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000216#include <nlist.h>
217#include <link.h>
218#else
Guido van Rossum504f4a91996-08-20 19:59:07 +0000219#ifdef HAVE_DLFCN_H
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000220#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000221#endif
Guido van Rossum504f4a91996-08-20 19:59:07 +0000222#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000223#ifndef _DL_FUNCPTR_DEFINED
224typedef void (*dl_funcptr)();
225#endif
226#ifndef RTLD_LAZY
227#define RTLD_LAZY 1
228#endif
229#define SHORT_EXT ".so"
230#define LONG_EXT "module.so"
231#endif /* USE_SHLIB */
232
233#if defined(USE_DL) || defined(hpux)
234#include "dl.h"
235#endif
236
Jack Jansen5d9acb61995-06-14 14:54:25 +0000237#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000238#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000239#include <CodeFragments.h>
Guido van Rossum79f25d91997-04-29 20:08:16 +0000240#ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000241#define CFragConnectionID ConnectionID
242#define kLoadCFrag 0x01
243#endif
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000244#ifdef USE_GUSI
245#include "TFileSpec.h" /* for Path2FSSpec() */
246#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000247#include <Files.h>
248#include "macdefs.h"
249#include "macglue.h"
250#endif
251
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000252#ifdef USE_RLD
253#include <mach-o/rld.h>
254#define FUNCNAME_PATTERN "_init%.200s"
255#ifndef _DL_FUNCPTR_DEFINED
256typedef void (*dl_funcptr)();
257#endif
258#endif /* USE_RLD */
259
Guido van Rossum79f25d91997-04-29 20:08:16 +0000260extern char *Py_GetProgramName();
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000261
262#ifndef FUNCNAME_PATTERN
Guido van Rossum65f15d41998-09-30 14:34:52 +0000263#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) && !defined(__ELF__) || defined(__OpenBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000264#define FUNCNAME_PATTERN "_init%.200s"
265#else
266#define FUNCNAME_PATTERN "init%.200s"
267#endif
268#endif
269
270#if !defined(SHORT_EXT) && !defined(LONG_EXT)
271#define SHORT_EXT ".o"
272#define LONG_EXT "module.o"
273#endif /* !SHORT_EXT && !LONG_EXT */
274
275#endif /* DYNAMIC_LINK */
276
Guido van Rossum79f25d91997-04-29 20:08:16 +0000277struct filedescr _PyImport_Filetab[] = {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000278#ifdef SHORT_EXT
279 {SHORT_EXT, "rb", C_EXTENSION},
280#endif /* !SHORT_EXT */
281#ifdef LONG_EXT
282 {LONG_EXT, "rb", C_EXTENSION},
283#endif /* !LONG_EXT */
284 {".py", "r", PY_SOURCE},
285 {".pyc", "rb", PY_COMPILED},
286 {0, 0}
287};
288
Guido van Rossum38234201996-07-31 17:55:19 +0000289#ifdef NO_DYNAMIC_LINK
290#undef DYNAMIC_LINK
291#endif
292
Guido van Rossum79f25d91997-04-29 20:08:16 +0000293PyObject *
294_PyImport_LoadDynamicModule(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000295 char *name;
296 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000297 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000298{
299#ifndef DYNAMIC_LINK
Guido van Rossum79f25d91997-04-29 20:08:16 +0000300 PyErr_SetString(PyExc_ImportError,
301 "dynamically linked modules not supported");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000302 return NULL;
303#else
Guido van Rossum79f25d91997-04-29 20:08:16 +0000304 PyObject *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000305 char funcname[258];
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000306 char *lastdot, *shortname, *packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000307 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000308#ifdef USE_SHLIB
309 static struct {
310 dev_t dev;
311 ino_t ino;
312 void *handle;
313 } handles[128];
314 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000315 char pathbuf[260];
316 if (strchr(pathname, '/') == NULL) {
317 /* Prefix bare filename with "./" */
318 sprintf(pathbuf, "./%-.255s", pathname);
319 pathname = pathbuf;
320 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000321#endif
Guido van Rossum25ce5661997-08-02 03:10:38 +0000322 if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
323 Py_INCREF(m);
324 return m;
325 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000326 lastdot = strrchr(name, '.');
327 if (lastdot == NULL) {
328 packagecontext = NULL;
329 shortname = name;
330 }
331 else {
332 packagecontext = name;
333 shortname = lastdot+1;
334 }
335 sprintf(funcname, FUNCNAME_PATTERN, shortname);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000336#ifdef USE_SHLIB
337 if (fp != NULL) {
338 int i;
339 struct stat statb;
340 fstat(fileno(fp), &statb);
341 for (i = 0; i < nhandles; i++) {
342 if (statb.st_dev == handles[i].dev &&
343 statb.st_ino == handles[i].ino) {
344 p = (dl_funcptr) dlsym(handles[i].handle,
345 funcname);
346 goto got_it;
347 }
348 }
349 if (nhandles < 128) {
350 handles[nhandles].dev = statb.st_dev;
351 handles[nhandles].ino = statb.st_ino;
352 }
353 }
354#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000355#ifdef USE_MAC_DYNAMIC_LOADING
356 /*
Guido van Rossum79f25d91997-04-29 20:08:16 +0000357 ** Dynamic loading of CFM shared libraries on the Mac. The
358 ** code has become more convoluted than it was, because we
359 ** want to be able to put multiple modules in a single
360 ** file. For this reason, we have to determine the fragment
361 ** name, and we cannot use the library entry point but we have
362 ** to locate the correct init routine "by hand".
Jack Jansen5d9acb61995-06-14 14:54:25 +0000363 */
Jack Jansen4e043731995-02-13 22:42:34 +0000364 {
365 FSSpec libspec;
366 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000367 Ptr mainAddr;
368 Str255 errMessage;
369 OSErr err;
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000370#ifndef USE_GUSI
Jack Jansen5d9acb61995-06-14 14:54:25 +0000371 Boolean isfolder, didsomething;
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000372#endif
Jack Jansen5d9acb61995-06-14 14:54:25 +0000373 char buf[512];
374 Str63 fragname;
375 Ptr symAddr;
376 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000377
Jack Jansen5d9acb61995-06-14 14:54:25 +0000378 /* First resolve any aliases to find the real file */
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000379#ifdef USE_GUSI
380 err = Path2FSSpec(pathname, &libspec);
381#else
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);
Guido van Rossuma0f0a331998-09-14 13:40:53 +0000384#endif
Jack Jansen5d9acb61995-06-14 14:54:25 +0000385 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000386 sprintf(buf, "%.255s: %.200s",
387 pathname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000388 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000389 return NULL;
390 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000391 /* Next, determine the fragment name,
392 by stripping '.slb' and 'module' */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000393 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
394 fragname[0] = libspec.name[0];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000395 if( strncmp((char *)(fragname+1+fragname[0]-4),
396 ".slb", 4) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000397 fragname[0] -= 4;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000398 if ( strncmp((char *)(fragname+1+fragname[0]-6),
399 "module", 6) == 0 )
Jack Jansen5d9acb61995-06-14 14:54:25 +0000400 fragname[0] -= 6;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000401 /* Load the fragment
402 (or return the connID if it is already loaded */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000403 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000404 kLoadCFrag, &connID, &mainAddr,
405 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000406 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000407 sprintf(buf, "%.*s: %.200s",
408 errMessage[0], errMessage+1,
Guido van Rossum79f25d91997-04-29 20:08:16 +0000409 PyMac_StrError(err));
410 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen4e043731995-02-13 22:42:34 +0000411 return NULL;
412 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000413 /* Locate the address of the correct init function */
414 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
415 if ( err ) {
Guido van Rossumbc2472d1997-04-30 19:07:54 +0000416 sprintf(buf, "%s: %.200s",
417 funcname, PyMac_StrError(err));
Guido van Rossum79f25d91997-04-29 20:08:16 +0000418 PyErr_SetString(PyExc_ImportError, buf);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000419 return NULL;
420 }
421 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000422 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000423#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000424#ifdef USE_SHLIB
425 {
426#ifdef RTLD_NOW
427 /* RTLD_NOW: resolve externals now
428 (i.e. core dump now if some are missing) */
Guido van Rossum6b077871998-05-18 13:42:45 +0000429 void *handle = dlopen(pathname, RTLD_NOW);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000430#else
431 void *handle;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000432 if (Py_VerboseFlag)
Guido van Rossum08052c71997-12-02 20:43:18 +0000433 printf("dlopen(\"%s\", %d);\n", pathname,
Guido van Rossum6b077871998-05-18 13:42:45 +0000434 RTLD_LAZY);
435 handle = dlopen(pathname, RTLD_LAZY);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000436#endif /* RTLD_NOW */
437 if (handle == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000438 PyErr_SetString(PyExc_ImportError, dlerror());
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000439 return NULL;
440 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000441 if (fp != NULL && nhandles < 128)
442 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000443 p = (dl_funcptr) dlsym(handle, funcname);
444 }
445#endif /* USE_SHLIB */
446#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000447 /*
448 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
449 -- of the shared module unresolved. Thus we have to resolve them
450 -- explicitely with loadbind. The new module is loaded, then we
451 -- resolve its symbols using the list of already loaded modules
452 -- (only those that belong to the python executable). Get these
453 -- with loadquery(L_GETINFO).
454 */
455 {
456 static void *staticmodlistptr = NULL;
457
458 if (!staticmodlistptr)
459 if (aix_getoldmodules(&staticmodlistptr) == -1)
460 return NULL;
461 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
462 if (p == NULL) {
463 aix_loaderror(pathname);
464 return NULL;
465 }
466 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
467 aix_loaderror(pathname);
468 return NULL;
469 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000470 }
471#endif /* _AIX */
Guido van Rossum9b38a141996-09-11 23:12:24 +0000472#ifdef MS_WIN32
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000473 {
474 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000475 char pathbuf[260];
476 if (strchr(pathname, SEP) == NULL &&
477 strchr(pathname, ALTSEP) == NULL)
478 {
479 /* Prefix bare filename with ".\" */
480 char *p = pathbuf;
481 *p = '\0';
482 _getcwd(pathbuf, sizeof pathbuf);
483 if (*p != '\0' && p[1] == ':')
484 p += 2;
485 sprintf(p, ".\\%-.255s", pathname);
486 pathname = pathbuf;
487 }
Guido van Rossum0f8b30f1998-10-08 01:44:41 +0000488 /* Look for dependent DLLs in directory of pathname first */
489 /* XXX This call doesn't exist in Windows CE */
490 hDLL = LoadLibraryEx(pathname, NULL,
491 LOAD_WITH_ALTERED_SEARCH_PATH);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000492 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000493 char errBuf[256];
494 unsigned int errorCode;
495
496 /* Get an error string from Win32 error code */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000497 char theInfo[256]; /* Pointer to error text
498 from system */
499 int theLength; /* Length of error text */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000500
501 errorCode = GetLastError();
502
Guido van Rossum79f25d91997-04-29 20:08:16 +0000503 theLength = FormatMessage(
504 FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
505 NULL, /* message source */
506 errorCode, /* the message (error) ID */
507 0, /* default language environment */
508 (LPTSTR) theInfo, /* the buffer */
509 sizeof(theInfo), /* the buffer size */
510 NULL); /* no additional format args. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000511
Guido van Rossum79f25d91997-04-29 20:08:16 +0000512 /* Problem: could not get the error message.
513 This should not happen if called correctly. */
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000514 if (theLength == 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000515 sprintf(errBuf,
516 "DLL load failed with error code %d",
517 errorCode);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000518 } else {
519 int len;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000520 /* For some reason a \r\n
521 is appended to the text */
522 if (theLength >= 2 &&
523 theInfo[theLength-2] == '\r' &&
524 theInfo[theLength-1] == '\n') {
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000525 theLength -= 2;
526 theInfo[theLength] = '\0';
527 }
528 strcpy(errBuf, "DLL load failed: ");
529 len = strlen(errBuf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000530 strncpy(errBuf+len, theInfo,
531 sizeof(errBuf)-len);
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000532 errBuf[sizeof(errBuf)-1] = '\0';
533 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000534 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000535 return NULL;
536 }
537 p = GetProcAddress(hDLL, funcname);
538 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000539#endif /* MS_WIN32 */
540#ifdef MS_WIN16
Guido van Rossumdadc8241996-05-23 22:51:40 +0000541 {
542 HINSTANCE hDLL;
Guido van Rossuma5e1b001998-06-27 21:53:17 +0000543 char pathbuf[16];
544 if (strchr(pathname, SEP) == NULL &&
545 strchr(pathname, ALTSEP) == NULL)
546 {
547 /* Prefix bare filename with ".\" */
548 sprintf(pathbuf, ".\\%-.13s", pathname);
549 pathname = pathbuf;
550 }
Guido van Rossumdadc8241996-05-23 22:51:40 +0000551 hDLL = LoadLibrary(pathname);
552 if (hDLL < HINSTANCE_ERROR){
553 char errBuf[256];
Guido van Rossum79f25d91997-04-29 20:08:16 +0000554 sprintf(errBuf,
555 "DLL load failed with error code %d", hDLL);
556 PyErr_SetString(PyExc_ImportError, errBuf);
Guido van Rossumdadc8241996-05-23 22:51:40 +0000557 return NULL;
558 }
559 p = GetProcAddress(hDLL, funcname);
560 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000561#endif /* MS_WIN16 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000562
563#if defined(PYOS_OS2)
564 {
565 APIRET rc;
566 HMODULE hDLL;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000567 char failreason[256];
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000568
569 rc = DosLoadModule(failreason,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000570 sizeof(failreason),
571 pathname,
572 &hDLL);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000573
574 if (rc != NO_ERROR) {
575 char errBuf[256];
576 sprintf(errBuf,
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000577 "DLL load failed, rc = %d, problem '%s': %s",
578 rc, failreason);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000579 PyErr_SetString(PyExc_ImportError, errBuf);
580 return NULL;
581 }
582
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000583 rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
584 if (rc != NO_ERROR)
585 p = NULL; /* Signify Failure to Acquire Entrypoint */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000586 }
587#endif /* PYOS_OS2 */
588
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000589#ifdef USE_DL
Guido van Rossum79f25d91997-04-29 20:08:16 +0000590 p = dl_loadmod(Py_GetProgramName(), pathname, funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000591#endif /* USE_DL */
592#ifdef USE_RLD
593 {
594 NXStream *errorStream;
595 struct mach_header *new_header;
596 const char *filenames[2];
597 long ret;
598 unsigned long ptr;
599
600 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
601 filenames[0] = pathname;
602 filenames[1] = NULL;
Guido van Rossumab076fd1998-08-24 14:15:44 +0000603
604#if HANDLE_OBJC_MODULES
605
606/* The following very bogus line of code ensures that
607 objc_msgSend, etc are linked into the binary. Without
608 it, dynamic loading of a module that includes objective-c
609 method calls will fail with "undefined symbol _objc_msgSend()".
610 This remains true even in the presence of the -ObjC flag
611 to the compiler
612*/
613
614 [Object name];
615
616/* objc_loadModules() dynamically loads the object files
617 indicated by the paths in filenames. If there are any
618 errors generated during loading -- typically due to the
619 inability to find particular symbols -- an error message
620 will be written to errorStream.
621 It returns 0 if the module is successfully loaded, 1
622 otherwise.
623*/
624
625 ret = !objc_loadModules(filenames, errorStream,
626 NULL, &new_header, NULL);
627
628#else /* !HANDLE_OBJC_MODULES */
629
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000630 ret = rld_load(errorStream, &new_header,
631 filenames, NULL);
632
Guido van Rossumab076fd1998-08-24 14:15:44 +0000633#endif /* HANDLE_OBJC_MODULES */
634
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000635 /* extract the error messages for the exception */
636 if(!ret) {
637 char *streamBuf;
638 int len, maxLen;
639
640 NXPutc(errorStream, (char)0);
641
642 NXGetMemoryBuffer(errorStream,
643 &streamBuf, &len, &maxLen);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000644 PyErr_SetString(PyExc_ImportError, streamBuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000645 }
646
647 if(ret && rld_lookup(errorStream, funcname, &ptr))
648 p = (dl_funcptr) ptr;
649
650 NXCloseMemory(errorStream, NX_FREEBUFFER);
651
652 if(!ret)
653 return NULL;
654 }
655#endif /* USE_RLD */
656#ifdef hpux
657 {
658 shl_t lib;
659 int flags;
660
Guido van Rossum3afb5951996-12-05 23:15:35 +0000661 flags = BIND_FIRST | BIND_DEFERRED;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000662 if (Py_VerboseFlag) {
663 flags = DYNAMIC_PATH | BIND_FIRST | BIND_IMMEDIATE |
Guido van Rossum79f25d91997-04-29 20:08:16 +0000664 BIND_NONFATAL | BIND_VERBOSE;
Guido van Rossumbb71ab61998-07-08 13:47:12 +0000665 printf("shl_load %s\n",pathname);
666 }
667 lib = shl_load(pathname, flags, 0);
668 /* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
669 if (lib == NULL) {
670 char buf[256];
671 if (Py_VerboseFlag)
672 perror(pathname);
673 sprintf(buf, "Failed to load %.200s", pathname);
674 PyErr_SetString(PyExc_ImportError, buf);
675 return NULL;
676 }
677 if (Py_VerboseFlag)
678 printf("shl_findsym %s\n", funcname);
679 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
680 if (p == NULL && Py_VerboseFlag)
681 perror(funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000682 }
683#endif /* hpux */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000684#ifdef __BEOS__
685 {
686 image_id the_id;
687 status_t retval;
688 char fullpath[PATH_MAX];
689
690 if( Py_VerboseFlag ) {
691 printf( "load_add_on( %s )\n", pathname );
692 }
693
694 /* Hmm, this old bug appears to have regenerated itself; if the
695 * path isn't absolute, load_add_on() will fail. Reported to Be
696 * April 21, 1998.
697 */
698 if( pathname[0] != '/' ) {
699 (void)getcwd( fullpath, PATH_MAX );
700 (void)strncat( fullpath, "/", PATH_MAX );
701 (void)strncat( fullpath, pathname, PATH_MAX );
702
703 if( Py_VerboseFlag ) {
704 printf( "load_add_on( %s )\n", fullpath );
705 }
706 } else {
707 (void)strcpy( fullpath, pathname );
708 }
709
710 the_id = load_add_on( fullpath );
711 if( the_id < B_NO_ERROR ) {
712 /* It's too bad load_add_on() doesn't set errno or something...
713 */
714 char buff[256]; /* hate hard-coded string sizes... */
715
716 if( Py_VerboseFlag ) {
717 printf( "load_add_on( %s ) failed", fullpath );
718 }
719
720 switch( the_id ) {
721 case B_ERROR:
722 sprintf( buff, "BeOS: Failed to load %.200s", fullpath );
723 break;
724 default:
725 sprintf( buff, "Unknown error loading %.200s", fullpath );
726 break;
727 }
728
729 PyErr_SetString( PyExc_ImportError, buff );
730 return NULL;
731 }
732
733 if( Py_VerboseFlag ) {
734 printf( "get_image_symbol( %s )\n", funcname );
735 }
736
737 retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
738 if( retval != B_NO_ERROR || p == NULL ) {
739 /* That's bad, we can't find that symbol in the module...
740 */
741 char buff[256]; /* hate hard-coded string sizes... */
742
743 if( Py_VerboseFlag ) {
744 printf( "get_image_symbol( %s ) failed", funcname );
745 }
746
747 switch( retval ) {
748 case B_BAD_IMAGE_ID:
749 sprintf( buff, "can't load init function for dynamic module: "
750 "Invalid image ID for %.180s", fullpath );
751 break;
752 case B_BAD_INDEX:
753 sprintf( buff, "can't load init function for dynamic module: "
754 "Bad index for %.180s", funcname );
755 break;
756 default:
757 sprintf( buff, "can't load init function for dynamic module: "
758 "Unknown error looking up %.180s", funcname );
759 break;
760 }
761
762 retval = unload_add_on( the_id );
763
764 PyErr_SetString( PyExc_ImportError, buff );
765 return NULL;
766 }
767
768 /* Save the module name and image ID for later so we can clean up
769 * gracefully.
770 */
771 beos_add_dyn( name, the_id );
772 }
773#endif /* __BEOS__ */
Guido van Rossum644a12b1997-04-09 19:24:53 +0000774#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000775 got_it:
Guido van Rossum644a12b1997-04-09 19:24:53 +0000776#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000777 if (p == NULL) {
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000778 PyErr_Format(PyExc_ImportError,
Guido van Rossum42e8e5d1998-01-19 22:23:08 +0000779 "dynamic module does not define init function (%.200s)",
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000780 funcname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000781 return NULL;
782 }
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000783 _Py_PackageContext = packagecontext;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000784 (*p)();
Guido van Rossum2e58ff31997-11-19 18:53:33 +0000785 _Py_PackageContext = NULL;
Guido van Rossum25ce5661997-08-02 03:10:38 +0000786 if (PyErr_Occurred())
787 return NULL;
788 if (_PyImport_FixupExtension(name, pathname) == NULL)
789 return NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000790
Guido van Rossumef3d02e1997-07-21 14:54:36 +0000791 m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000792 if (m == NULL) {
Guido van Rossum25ce5661997-08-02 03:10:38 +0000793 PyErr_SetString(PyExc_SystemError,
794 "dynamic module not initialized properly");
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000795 return NULL;
796 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000797 /* Remember the filename as the __file__ attribute */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000798 d = PyModule_GetDict(m);
799 s = PyString_FromString(pathname);
800 if (s == NULL || PyDict_SetItemString(d, "__file__", s) != 0)
801 PyErr_Clear(); /* Not important enough to report */
802 Py_XDECREF(s);
803 if (Py_VerboseFlag)
Guido van Rossum2f3667a1998-10-12 18:23:55 +0000804 PySys_WriteStderr(
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000805 "import %s # dynamically loaded from %s\n",
806 name, pathname);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000807 Py_INCREF(m);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000808 return m;
809#endif /* DYNAMIC_LINK */
810}
811
812
813#ifdef _AIX
814
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000815#include <ctype.h> /* for isdigit() */
816#include <errno.h> /* for global errno */
817#include <string.h> /* for strerror() */
818#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000819
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000820typedef struct Module {
821 struct Module *next;
822 void *entry;
823} Module, *ModulePtr;
824
825static int
826aix_getoldmodules(modlistptr)
827 void **modlistptr;
828{
829 register ModulePtr modptr, prevmodptr;
830 register struct ld_info *ldiptr;
831 register char *ldibuf;
832 register int errflag, bufsize = 1024;
833 register unsigned int offset;
834
835 /*
836 -- Get the list of loaded modules into ld_info structures.
837 */
838 if ((ldibuf = malloc(bufsize)) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000839 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000840 return -1;
841 }
842 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
843 && errno == ENOMEM) {
844 free(ldibuf);
845 bufsize += 1024;
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 }
851 if (errflag == -1) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000852 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000853 return -1;
854 }
855 /*
856 -- Make the modules list from the ld_info structures.
857 */
858 ldiptr = (struct ld_info *)ldibuf;
859 prevmodptr = NULL;
860 do {
Guido van Rossum3b31cd21997-10-10 17:40:00 +0000861 if (strstr(ldiptr->ldinfo_filename, "python") == NULL) {
862 /*
863 -- Extract only the modules containing "python" as a
864 -- substring, like the "python[version]" executable or
865 -- "libpython[version].a" in case python is embedded.
866 */
867 offset = (unsigned int)ldiptr->ldinfo_next;
868 ldiptr = (struct ld_info *)((unsigned int)
869 ldiptr + offset);
870 continue;
871 }
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000872 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000873 PyErr_SetString(PyExc_ImportError, strerror(errno));
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000874 while (*modlistptr) {
875 modptr = (ModulePtr)*modlistptr;
876 *modlistptr = (void *)modptr->next;
877 free(modptr);
878 }
879 return -1;
880 }
881 modptr->entry = ldiptr->ldinfo_dataorg;
882 modptr->next = NULL;
883 if (prevmodptr == NULL)
884 *modlistptr = (void *)modptr;
885 else
886 prevmodptr->next = modptr;
887 prevmodptr = modptr;
888 offset = (unsigned int)ldiptr->ldinfo_next;
889 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
890 } while (offset);
891 free(ldibuf);
892 return 0;
893}
894
895static int
896aix_bindnewmodule(newmoduleptr, modlistptr)
897 void *newmoduleptr;
898 void *modlistptr;
899{
900 register ModulePtr modptr;
901
902 /*
903 -- Bind the new module with the list of loaded modules.
904 */
905 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
906 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
907 return -1;
908 return 0;
909}
910
911static void
912aix_loaderror(pathname)
913 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000914{
915
Guido van Rossum236f62d1996-06-26 21:07:08 +0000916 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000917 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000918
919 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000920 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000921 char *errstr;
922 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000923 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000924 {L_ERROR_NOLIB, "can't load library:"},
925 {L_ERROR_UNDEF, "can't find symbol in library:"},
926 {L_ERROR_RLDBAD,
927 "RLD index out of range or bad relocation type:"},
928 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
929 {L_ERROR_MEMBER,
930 "file not an archive or does not contain requested member:"},
931 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000932 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000933 {L_ERROR_SYSTEM, "System error:"},
934 {L_ERROR_ERRNO, NULL}
935 };
936
937#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
938#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
939
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000940 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000941
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000942 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000943 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000944 ERRBUF_APPEND("\n");
945 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000946 for(i = 0; message[i] && *message[i]; i++) {
947 int nerr = atoi(message[i]);
948 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000949 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000950 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000951 }
952 while (isdigit(*message[i])) message[i]++ ;
953 ERRBUF_APPEND(message[i]);
954 ERRBUF_APPEND("\n");
955 }
956 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000957 PyErr_SetString(PyExc_ImportError, errbuf);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000958 return;
959}
960
961#endif /* _AIX */
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000962
963#ifdef __BEOS__
964/* ----------------------------------------------------------------------
965 * BeOS dynamic loading support
966 *
967 * This uses shared libraries, but BeOS has its own way of doing things
968 * (much easier than dlfnc.h, from the look of things). We'll use a
969 * Python Dictionary object to store the images_ids so we can be very
970 * nice and unload them when we exit.
971 *
972 * Note that this is thread-safe. Probably irrelevent, because of losing
973 * systems... Python probably disables threads while loading modules.
974 * Note the use of "probably"! Better to be safe than sorry. [chrish]
975 *
976 * As of 1.5.1 this should also work properly when you've configured
977 * Python without thread support; the 1.5 version required it, which wasn't
978 * very friendly. Note that I haven't tested it without threading... why
979 * would you want to avoid threads on BeOS? [chrish]
Guido van Rossumcad3d471999-01-04 16:45:59 +0000980 *
981 * As of 1.5.2, the PyImport_BeImageID() function has been removed; Donn
982 * tells me it's not necessary anymore because of PyCObject_Import().
983 * [chrish]
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000984 */
985
986/*
987 * Initialize our dictionary, and the dictionary mutex.
988 */
989static void beos_init_dyn( void )
990{
991 /* We're protected from a race condition here by the atomic init_count
992 * variable.
993 */
994 static int32 init_count = 0;
995 int32 val;
996
997 val = atomic_add( &init_count, 1 );
998 if( beos_dyn_images == NULL && val == 0 ) {
999 beos_dyn_images = PyDict_New();
1000#ifdef WITH_THREAD
1001 beos_dyn_lock = PyThread_allocate_lock();
1002#endif
1003 atexit( beos_cleanup_dyn );
1004 }
1005}
1006
1007/* atexit() handler that'll call unload_add_on() for every item in the
1008 * dictionary.
1009 */
1010static void beos_cleanup_dyn( void )
1011{
1012 if( beos_dyn_images ) {
1013 int idx;
1014 int list_size;
1015 PyObject *id_list;
1016
1017#ifdef WITH_THREAD
1018 PyThread_acquire_lock( beos_dyn_lock, 1 );
1019#endif
1020
1021 id_list = PyDict_Values( beos_dyn_images );
1022
1023 list_size = PyList_Size( id_list );
1024 for( idx = 0; idx < list_size; idx++ ) {
1025 PyObject *the_item;
1026
1027 the_item = PyList_GetItem( id_list, idx );
1028 beos_nuke_dyn( the_item );
1029 }
1030
1031 PyDict_Clear( beos_dyn_images );
1032
1033#ifdef WITH_THREAD
1034 PyThread_free_lock( beos_dyn_lock );
1035#endif
1036 }
1037}
1038
1039/* Whack an item; the item is an image_id in disguise, so we'll call
1040 * unload_add_on() for it.
1041 */
1042static void beos_nuke_dyn( PyObject *item )
1043{
1044 status_t retval;
1045
1046 if( item ) {
1047 image_id id = (image_id)PyInt_AsLong( item );
1048
1049 retval = unload_add_on( id );
1050 }
1051}
1052
1053/*
1054 * Add an image_id to the dictionary; the module name of the loaded image
1055 * is the key. Note that if the key is already in the dict, we unload
1056 * that image; this should allow reload() to work on dynamically loaded
1057 * modules (super-keen!).
1058 */
1059static void beos_add_dyn( char *name, image_id id )
1060{
1061 int retval;
1062 PyObject *py_id;
1063
1064 if( beos_dyn_images == NULL ) {
1065 beos_init_dyn();
1066 }
1067
1068#ifdef WITH_THREAD
1069 retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
1070#endif
1071
1072 /* If there's already an object with this key in the dictionary,
1073 * we're doing a reload(), so let's nuke it.
1074 */
1075 py_id = PyDict_GetItemString( beos_dyn_images, name );
1076 if( py_id ) {
1077 beos_nuke_dyn( py_id );
1078 retval = PyDict_DelItemString( beos_dyn_images, name );
1079 }
1080
1081 py_id = PyInt_FromLong( (long)id );
1082 if( py_id ) {
1083 retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
1084 }
1085
1086#ifdef WITH_THREAD
1087 PyThread_release_lock( beos_dyn_lock );
1088#endif
1089}
1090
Guido van Rossum1a8791e1998-08-04 22:46:29 +00001091#endif /* __BEOS__ */