blob: 6a56648f0f481a22dfa0beef5f1f7ab72d79ed8f [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum22a1d361999-12-20 21:18:49 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum22a1d361999-12-20 21:18:49 +00009******************************************************************/
10
11/* Support for dynamic loading of extension modules */
12
13#include "Python.h"
14#include "importdl.h"
15
16#include <sys/types.h>
17#include <sys/stat.h>
18#if defined(__NetBSD__) && (NetBSD < 199712)
19#include <nlist.h>
20#include <link.h>
21#define dlerror() "error in dynamic linking"
22#else
23#ifdef HAVE_DLFCN_H
24#include <dlfcn.h>
25#endif
26#endif
27
28#ifndef RTLD_LAZY
29#define RTLD_LAZY 1
30#endif
31
32
33const struct filedescr _PyImport_DynLoadFiletab[] = {
34 {".so", "rb", C_EXTENSION},
35 {"module.so", "rb", C_EXTENSION},
36 {0, 0}
37};
38
39static struct {
40 dev_t dev;
41 ino_t ino;
42 void *handle;
43} handles[128];
44static int nhandles = 0;
45
46
Guido van Rossum96a8fb71999-12-22 14:09:35 +000047dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000048 const char *pathname, FILE *fp)
49{
50 dl_funcptr p;
51 void *handle;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000052 char funcname[258];
53 char pathbuf[260];
54
55 if (strchr(pathname, '/') == NULL) {
56 /* Prefix bare filename with "./" */
57 sprintf(pathbuf, "./%-.255s", pathname);
58 pathname = pathbuf;
59 }
60
61 /* ### should there be a leading underscore for some platforms? */
62 sprintf(funcname, "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +000063
64 if (fp != NULL) {
65 int i;
66 struct stat statb;
67 fstat(fileno(fp), &statb);
68 for (i = 0; i < nhandles; i++) {
69 if (statb.st_dev == handles[i].dev &&
70 statb.st_ino == handles[i].ino) {
71 p = (dl_funcptr) dlsym(handles[i].handle,
72 funcname);
73 return p;
74 }
75 }
76 if (nhandles < 128) {
77 handles[nhandles].dev = statb.st_dev;
78 handles[nhandles].ino = statb.st_ino;
79 }
80 }
81
82#ifdef RTLD_NOW
83 /* RTLD_NOW: resolve externals now
84 (i.e. core dump now if some are missing) */
85 handle = dlopen(pathname, RTLD_NOW);
86#else
87 if (Py_VerboseFlag)
88 printf("dlopen(\"%s\", %d);\n", pathname,
89 RTLD_LAZY);
90 handle = dlopen(pathname, RTLD_LAZY);
91#endif /* RTLD_NOW */
92 if (handle == NULL) {
93 PyErr_SetString(PyExc_ImportError, dlerror());
94 return NULL;
95 }
96 if (fp != NULL && nhandles < 128)
97 handles[nhandles++].handle = handle;
98 p = (dl_funcptr) dlsym(handle, funcname);
99 return p;
100}