diff --git a/Python/import.c b/Python/import.c index 155ce34b37c..6eeefdf3f6d 100644 --- a/Python/import.c +++ b/Python/import.c @@ -487,7 +487,7 @@ load_module(name) break; case C_EXTENSION: - m = load_dynamic_module(name, buf); + m = load_dynamic_module(name, buf, fp); break; #ifdef macintosh @@ -868,7 +868,7 @@ imp_load_dynamic(self, args) object *dummy; if (!newgetargs(args, "ss|O", &name, &pathname, &dummy)) return NULL; - return load_dynamic_module(name, pathname); + return load_dynamic_module(name, pathname, NULL); } static object * diff --git a/Python/importdl.c b/Python/importdl.c index 0d13a14e9d7..f8c0c23af16 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -127,6 +127,8 @@ static void aix_loaderror(char *name); #ifdef DYNAMIC_LINK #ifdef USE_SHLIB +#include +#include #ifdef __NetBSD__ #include #include @@ -204,9 +206,10 @@ struct filedescr import_filetab[] = { }; object * -load_dynamic_module(name, pathname) +load_dynamic_module(name, pathname, fp) char *name; char *pathname; + FILE *fp; { #ifndef DYNAMIC_LINK err_setstr(ImportError, "dynamically linked modules not supported"); @@ -215,7 +218,34 @@ load_dynamic_module(name, pathname) object *m; char funcname[258]; dl_funcptr p = NULL; +#ifdef USE_SHLIB + static struct { + dev_t dev; + ino_t ino; + void *handle; + } handles[128]; + static int nhandles = 0; +#endif sprintf(funcname, FUNCNAME_PATTERN, name); +#ifdef USE_SHLIB + if (fp != NULL) { + int i; + struct stat statb; + fstat(fileno(fp), &statb); + for (i = 0; i < nhandles; i++) { + if (statb.st_dev == handles[i].dev && + statb.st_ino == handles[i].ino) { + p = (dl_funcptr) dlsym(handles[i].handle, + funcname); + goto got_it; + } + } + if (nhandles < 128) { + handles[nhandles].dev = statb.st_dev; + handles[nhandles].ino = statb.st_ino; + } + } +#endif /* USE_SHLIB */ #ifdef USE_MAC_SHARED_LIBRARY /* Dynamic loading of CFM shared libraries on the Mac */ { @@ -255,6 +285,8 @@ load_dynamic_module(name, pathname) err_setstr(ImportError, dlerror()); return NULL; } + if (fp != NULL && nhandles < 128) + handles[nhandles++].handle = handle; p = (dl_funcptr) dlsym(handle, funcname); } #endif /* USE_SHLIB */ @@ -345,6 +377,7 @@ load_dynamic_module(name, pathname) perror(funcname); } #endif /* hpux */ + got_it: if (p == NULL) { err_setstr(ImportError, "dynamic module does not define init function"); @@ -385,7 +418,7 @@ void aix_loaderror(char *pathname) int errno; char *errstr; } load_errtab[] = { - {L_ERROR_TOOMANY, "to many errors, rest skipped."}, + {L_ERROR_TOOMANY, "too many errors, rest skipped."}, {L_ERROR_NOLIB, "can't load library:"}, {L_ERROR_UNDEF, "can't find symbol in library:"}, {L_ERROR_RLDBAD, diff --git a/Python/importdl.h b/Python/importdl.h index ea98ed5bfff..8dbf55f5d3b 100644 --- a/Python/importdl.h +++ b/Python/importdl.h @@ -37,6 +37,6 @@ extern struct filedescr { extern object *import_modules; -extern object *load_dynamic_module PROTO((char *name, char *pathname)); +extern object *load_dynamic_module PROTO((char *name, char *pathname, FILE *)); extern int import_maxsuffixsize;