blob: b1b13a160b6aea33a98a2e2b1e0421ccd4602270 [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
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Support for dynamic loading of extension modules */
26/* If no dynamic linking is supported, this file still generates some code! */
27
28#include "allobjects.h"
29#include "osdefs.h"
30#include "importdl.h"
31
Guido van Rossum1ae940a1995-01-02 19:04:15 +000032/* Explanation of some of the the various #defines used by dynamic linking...
33
34 symbol -- defined for:
35
36 DYNAMIC_LINK -- any kind of dynamic linking
Guido van Rossum75f288d1995-06-14 22:07:26 +000037 USE_RLD -- NeXT dynamic linking
Guido van Rossum1ae940a1995-01-02 19:04:15 +000038 USE_DL -- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
39 USE_SHLIB -- SunOS or IRIX 5 (SVR4?) shared libraries
40 _AIX -- AIX style dynamic linking
41 NT -- NT style dynamic linking (using DLLs)
Guido van Rossumdadc8241996-05-23 22:51:40 +000042 WIN16_DL -- Windows 16-bit dynamic linking (using DLLs)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000043 _DL_FUNCPTR_DEFINED -- if the typedef dl_funcptr has been defined
Jack Jansen5d9acb61995-06-14 14:54:25 +000044 USE_MAC_DYNAMIC_LOADING -- Mac CFM shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000045 SHORT_EXT -- short extension for dynamic module, e.g. ".so"
46 LONG_EXT -- long extension, e.g. "module.so"
47 hpux -- HP-UX Dynamic Linking - defined by the compiler
Guido van Rossum46c76a61995-01-20 16:53:54 +000048 __NetBSD__ -- NetBSD shared libraries (not quite SVR4 compatible)
Guido van Rossum25e85291996-02-25 05:02:29 +000049 __FreeBSD__ -- FreeBSD shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000050
51 (The other WITH_* symbols are used only once, to set the
52 appropriate symbols.)
53*/
54
55/* Configure dynamic linking */
56
Guido van Rossumff4af061996-01-12 01:17:50 +000057#ifdef __hpux
58#define hpux
59#endif
60
Guido van Rossum1ae940a1995-01-02 19:04:15 +000061#ifdef hpux
62#define DYNAMIC_LINK
63#include <errno.h>
64typedef void (*dl_funcptr)();
65#define _DL_FUNCPTR_DEFINED 1
66#define SHORT_EXT ".sl"
67#define LONG_EXT "module.sl"
68#endif
69
Guido van Rossum25e85291996-02-25 05:02:29 +000070#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +000071#define DYNAMIC_LINK
72#define USE_SHLIB
73
74#define dlerror() "error in dynamic linking"
75#endif
76
Guido van Rossum0fbec641995-02-27 10:15:36 +000077#ifdef __WIN32__
78#define NT
79#endif
80
Guido van Rossumdadc8241996-05-23 22:51:40 +000081#ifdef MS_WIN16
82#define WIN16_DL
83#endif
84
85#if defined(NT) || defined(WIN16_DL)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000086#define DYNAMIC_LINK
87#include <windows.h>
88typedef FARPROC dl_funcptr;
89#define _DL_FUNCPTR_DEFINED
Guido van Rossum5fb1da71995-01-07 12:36:02 +000090#define SHORT_EXT ".pyd"
Guido van Rossume71a9471996-04-09 02:39:15 +000091#define LONG_EXT ".dll"
Guido van Rossum1ae940a1995-01-02 19:04:15 +000092#endif
93
Guido van Rossum75f288d1995-06-14 22:07:26 +000094#ifdef NeXT
Guido van Rossum1ae940a1995-01-02 19:04:15 +000095#define DYNAMIC_LINK
96#define USE_RLD
97#endif
98
99#ifdef WITH_SGI_DL
100#define DYNAMIC_LINK
101#define USE_DL
102#endif
103
104#ifdef WITH_DL_DLD
105#define DYNAMIC_LINK
106#define USE_DL
107#endif
108
Guido van Rossum6a75d261995-02-18 14:51:15 +0000109#ifdef __CFM68K__
Jack Jansen5d9acb61995-06-14 14:54:25 +0000110#define USE_MAC_DYNAMIC_LOADING
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000111#endif
112
Jack Jansen5d9acb61995-06-14 14:54:25 +0000113#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen4e043731995-02-13 22:42:34 +0000114#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000115#define SHORT_EXT ".slb"
116#define LONG_EXT "module.slb"
Jack Jansen4e043731995-02-13 22:42:34 +0000117#ifndef _DL_FUNCPTR_DEFINED
118typedef void (*dl_funcptr)();
119#endif
120#endif
121
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000122#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
123#define DYNAMIC_LINK
124#define USE_SHLIB
125#endif
126
127#ifdef _AIX
128#define DYNAMIC_LINK
129#include <sys/ldr.h>
130typedef void (*dl_funcptr)();
131#define _DL_FUNCPTR_DEFINED
132static void aix_loaderror(char *name);
133#endif
134
135#ifdef DYNAMIC_LINK
136
137#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000138#include <sys/types.h>
139#include <sys/stat.h>
Guido van Rossum25e85291996-02-25 05:02:29 +0000140#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000141#include <nlist.h>
142#include <link.h>
143#else
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000144#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000145#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000146#ifndef _DL_FUNCPTR_DEFINED
147typedef void (*dl_funcptr)();
148#endif
149#ifndef RTLD_LAZY
150#define RTLD_LAZY 1
151#endif
152#define SHORT_EXT ".so"
153#define LONG_EXT "module.so"
154#endif /* USE_SHLIB */
155
156#if defined(USE_DL) || defined(hpux)
157#include "dl.h"
158#endif
159
Jack Jansen5d9acb61995-06-14 14:54:25 +0000160#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000161#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000162#include <CodeFragments.h>
Jack Janseneceb3e31995-06-27 13:15:15 +0000163#ifdef SYMANTEC__CFM68K__ /* Really just an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000164#define CFragConnectionID ConnectionID
165#define kLoadCFrag 0x01
166#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000167#include <Files.h>
168#include "macdefs.h"
169#include "macglue.h"
170#endif
171
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000172#ifdef USE_RLD
173#include <mach-o/rld.h>
174#define FUNCNAME_PATTERN "_init%.200s"
175#ifndef _DL_FUNCPTR_DEFINED
176typedef void (*dl_funcptr)();
177#endif
178#endif /* USE_RLD */
179
180extern char *getprogramname();
181
182#ifndef FUNCNAME_PATTERN
Guido van Rossum25e85291996-02-25 05:02:29 +0000183#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000184#define FUNCNAME_PATTERN "_init%.200s"
185#else
186#define FUNCNAME_PATTERN "init%.200s"
187#endif
188#endif
189
190#if !defined(SHORT_EXT) && !defined(LONG_EXT)
191#define SHORT_EXT ".o"
192#define LONG_EXT "module.o"
193#endif /* !SHORT_EXT && !LONG_EXT */
194
195#endif /* DYNAMIC_LINK */
196
Guido van Rossum6a75d261995-02-18 14:51:15 +0000197/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000198#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000199#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000200#endif
201
202/* Pass it on to import.c */
203int import_maxsuffixsize = MAXSUFFIXSIZE;
204
205struct filedescr import_filetab[] = {
206#ifdef SHORT_EXT
207 {SHORT_EXT, "rb", C_EXTENSION},
208#endif /* !SHORT_EXT */
209#ifdef LONG_EXT
210 {LONG_EXT, "rb", C_EXTENSION},
211#endif /* !LONG_EXT */
212 {".py", "r", PY_SOURCE},
213 {".pyc", "rb", PY_COMPILED},
214 {0, 0}
215};
216
Guido van Rossum38234201996-07-31 17:55:19 +0000217#ifdef NO_DYNAMIC_LINK
218#undef DYNAMIC_LINK
219#endif
220
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000221object *
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000222load_dynamic_module(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000223 char *name;
224 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000225 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000226{
227#ifndef DYNAMIC_LINK
228 err_setstr(ImportError, "dynamically linked modules not supported");
229 return NULL;
230#else
231 object *m;
232 char funcname[258];
233 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000234#ifdef USE_SHLIB
235 static struct {
236 dev_t dev;
237 ino_t ino;
238 void *handle;
239 } handles[128];
240 static int nhandles = 0;
241#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000242 sprintf(funcname, FUNCNAME_PATTERN, name);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000243#ifdef USE_SHLIB
244 if (fp != NULL) {
245 int i;
246 struct stat statb;
247 fstat(fileno(fp), &statb);
248 for (i = 0; i < nhandles; i++) {
249 if (statb.st_dev == handles[i].dev &&
250 statb.st_ino == handles[i].ino) {
251 p = (dl_funcptr) dlsym(handles[i].handle,
252 funcname);
253 goto got_it;
254 }
255 }
256 if (nhandles < 128) {
257 handles[nhandles].dev = statb.st_dev;
258 handles[nhandles].ino = statb.st_ino;
259 }
260 }
261#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000262#ifdef USE_MAC_DYNAMIC_LOADING
263 /*
264 ** Dynamic loading of CFM shared libraries on the Mac.
265 ** The code has become more convoluted than it was, because we want to be able
266 ** to put multiple modules in a single file. For this reason, we have to determine
267 ** the fragment name, and we cannot use the library entry point but we have to locate
268 ** the correct init routine "by hand".
269 */
Jack Jansen4e043731995-02-13 22:42:34 +0000270 {
271 FSSpec libspec;
272 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000273 Ptr mainAddr;
274 Str255 errMessage;
275 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000276 Boolean isfolder, didsomething;
277 char buf[512];
278 Str63 fragname;
279 Ptr symAddr;
280 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000281
Jack Jansen5d9acb61995-06-14 14:54:25 +0000282 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000283 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000284 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
285 if ( err ) {
286 sprintf(buf, "%s: %s", pathname, PyMac_StrError(err));
287 err_setstr(ImportError, buf);
288 return NULL;
289 }
290 /* Next, determine the fragment name, by stripping '.slb' and 'module' */
291 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
292 fragname[0] = libspec.name[0];
293 if( strncmp((char *)(fragname+1+fragname[0]-4), ".slb", 4) == 0 )
294 fragname[0] -= 4;
295 if ( strncmp((char *)(fragname+1+fragname[0]-6), "module", 6) == 0 )
296 fragname[0] -= 6;
297 /* Load the fragment (or return the connID if it is already loaded */
298 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000299 kLoadCFrag, &connID, &mainAddr,
300 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000301 if ( err ) {
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000302 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000303 err_setstr(ImportError, buf);
304 return NULL;
305 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000306 /* Locate the address of the correct init function */
307 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
308 if ( err ) {
309 sprintf(buf, "%s: %s", funcname, PyMac_StrError(err));
310 err_setstr(ImportError, buf);
311 return NULL;
312 }
313 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000314 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000315#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000316#ifdef USE_SHLIB
317 {
318#ifdef RTLD_NOW
319 /* RTLD_NOW: resolve externals now
320 (i.e. core dump now if some are missing) */
321 void *handle = dlopen(pathname, RTLD_NOW);
322#else
323 void *handle;
324 if (verbose)
325 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
326 handle = dlopen(pathname, RTLD_LAZY);
327#endif /* RTLD_NOW */
328 if (handle == NULL) {
329 err_setstr(ImportError, dlerror());
330 return NULL;
331 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000332 if (fp != NULL && nhandles < 128)
333 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000334 p = (dl_funcptr) dlsym(handle, funcname);
335 }
336#endif /* USE_SHLIB */
337#ifdef _AIX
338 p = (dl_funcptr) load(pathname, 1, 0);
339 if (p == NULL) {
340 aix_loaderror(pathname);
341 return NULL;
342 }
343#endif /* _AIX */
344#ifdef NT
345 {
346 HINSTANCE hDLL;
347 hDLL = LoadLibrary(pathname);
348 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000349 char errBuf[256];
350 unsigned int errorCode;
351
352 /* Get an error string from Win32 error code */
353 char theInfo[256]; /* Pointer to error text from system */
354 int theLength; /* Length of error text */
355
356 errorCode = GetLastError();
357
358 theLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
359 NULL, /* message source */
360 errorCode, /* the message (error) ID */
361 0, /* default language environment */
362 (LPTSTR) theInfo, /* the buffer */
363 sizeof(theInfo), /* the buffer size */
364 NULL); /* no additional format args. */
365
366 /* Problem: could not get the error message. This should not happen if called correctly. */
367 if (theLength == 0) {
368 sprintf(errBuf, "DLL load failed with error code %d", errorCode);
369 } else {
370 int len;
371 /* For some reason a \r\n is appended to the text */
372 if (theLength >= 2 && theInfo[theLength-2] == '\r' && theInfo[theLength-1] == '\n') {
373 theLength -= 2;
374 theInfo[theLength] = '\0';
375 }
376 strcpy(errBuf, "DLL load failed: ");
377 len = strlen(errBuf);
378 strncpy(errBuf+len, theInfo, sizeof(errBuf)-len);
379 errBuf[sizeof(errBuf)-1] = '\0';
380 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000381 err_setstr(ImportError, errBuf);
382 return NULL;
383 }
384 p = GetProcAddress(hDLL, funcname);
385 }
386#endif /* NT */
Guido van Rossumdadc8241996-05-23 22:51:40 +0000387#ifdef WIN16_DL
388 {
389 HINSTANCE hDLL;
390 hDLL = LoadLibrary(pathname);
391 if (hDLL < HINSTANCE_ERROR){
392 char errBuf[256];
393 sprintf(errBuf, "DLL load failed with error code %d", hDLL);
394 err_setstr(ImportError, errBuf);
395 return NULL;
396 }
397 p = GetProcAddress(hDLL, funcname);
398 }
399#endif /* WIN16_DL */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000400#ifdef USE_DL
401 p = dl_loadmod(getprogramname(), pathname, funcname);
402#endif /* USE_DL */
403#ifdef USE_RLD
404 {
405 NXStream *errorStream;
406 struct mach_header *new_header;
407 const char *filenames[2];
408 long ret;
409 unsigned long ptr;
410
411 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
412 filenames[0] = pathname;
413 filenames[1] = NULL;
414 ret = rld_load(errorStream, &new_header,
415 filenames, NULL);
416
417 /* extract the error messages for the exception */
418 if(!ret) {
419 char *streamBuf;
420 int len, maxLen;
421
422 NXPutc(errorStream, (char)0);
423
424 NXGetMemoryBuffer(errorStream,
425 &streamBuf, &len, &maxLen);
426 err_setstr(ImportError, streamBuf);
427 }
428
429 if(ret && rld_lookup(errorStream, funcname, &ptr))
430 p = (dl_funcptr) ptr;
431
432 NXCloseMemory(errorStream, NX_FREEBUFFER);
433
434 if(!ret)
435 return NULL;
436 }
437#endif /* USE_RLD */
438#ifdef hpux
439 {
440 shl_t lib;
441 int flags;
442
443 flags = BIND_DEFERRED;
444 if (verbose)
445 {
446 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
447 printf("shl_load %s\n",pathname);
448 }
449 lib = shl_load(pathname, flags, 0);
450 if (lib == NULL)
451 {
452 char buf[256];
453 if (verbose)
454 perror(pathname);
455 sprintf(buf, "Failed to load %.200s", pathname);
456 err_setstr(ImportError, buf);
457 return NULL;
458 }
459 if (verbose)
460 printf("shl_findsym %s\n", funcname);
461 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
462 if (p == NULL && verbose)
463 perror(funcname);
464 }
465#endif /* hpux */
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000466 got_it:
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000467 if (p == NULL) {
468 err_setstr(ImportError,
469 "dynamic module does not define init function");
470 return NULL;
471 }
472 (*p)();
473
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000474 m = dictlookup(import_modules, name);
475 if (m == NULL) {
476 if (err_occurred() == NULL)
477 err_setstr(SystemError,
478 "dynamic module not initialized properly");
479 return NULL;
480 }
481 if (verbose)
482 fprintf(stderr,
483 "import %s # dynamically loaded from %s\n",
484 name, pathname);
485 INCREF(m);
486 return m;
487#endif /* DYNAMIC_LINK */
488}
489
490
491#ifdef _AIX
492
493#include <ctype.h> /* for isdigit() */
494#include <errno.h> /* for global errno */
495#include <string.h> /* for strerror() */
496
497void aix_loaderror(char *pathname)
498{
499
Guido van Rossum236f62d1996-06-26 21:07:08 +0000500 char *message[1024], errbuf[1024];
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000501 int i,j;
502
503 struct errtab {
504 int errno;
505 char *errstr;
506 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000507 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000508 {L_ERROR_NOLIB, "can't load library:"},
509 {L_ERROR_UNDEF, "can't find symbol in library:"},
510 {L_ERROR_RLDBAD,
511 "RLD index out of range or bad relocation type:"},
512 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
513 {L_ERROR_MEMBER,
514 "file not an archive or does not contain requested member:"},
515 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000516 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000517 {L_ERROR_SYSTEM, "System error:"},
518 {L_ERROR_ERRNO, NULL}
519 };
520
521#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
522#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
523
524 sprintf(errbuf, " from module %.200s ", pathname);
525
Guido van Rossum236f62d1996-06-26 21:07:08 +0000526 if (!loadquery(1, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000527 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000528 ERRBUF_APPEND("\n");
529 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000530 for(i = 0; message[i] && *message[i]; i++) {
531 int nerr = atoi(message[i]);
532 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossum236f62d1996-06-26 21:07:08 +0000533 if (nerr == load_errtab[j].errno && load_errtab[j].errstr)
534 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000535 }
536 while (isdigit(*message[i])) message[i]++ ;
537 ERRBUF_APPEND(message[i]);
538 ERRBUF_APPEND("\n");
539 }
540 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
541 err_setstr(ImportError, errbuf);
542 return;
543}
544
545#endif /* _AIX */