ยปCore Development>Code coverage>Python/dynload_shlib.c

Python code coverage for Python/dynload_shlib.c

#countcontent
1n/a
2n/a/* Support for dynamic loading of extension modules */
3n/a
4n/a#include "Python.h"
5n/a#include "importdl.h"
6n/a
7n/a#include <sys/types.h>
8n/a#include <sys/stat.h>
9n/a
10n/a#if defined(__NetBSD__)
11n/a#include <sys/param.h>
12n/a#if (NetBSD < 199712)
13n/a#include <nlist.h>
14n/a#include <link.h>
15n/a#define dlerror() "error in dynamic linking"
16n/a#endif
17n/a#endif /* NetBSD */
18n/a
19n/a#ifdef HAVE_DLFCN_H
20n/a#include <dlfcn.h>
21n/a#endif
22n/a
23n/a#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
24n/a#define LEAD_UNDERSCORE "_"
25n/a#else
26n/a#define LEAD_UNDERSCORE ""
27n/a#endif
28n/a
29n/a/* The .so extension module ABI tag, supplied by the Makefile via
30n/a Makefile.pre.in and configure. This is used to discriminate between
31n/a incompatible .so files so that extensions for different Python builds can
32n/a live in the same directory. E.g. foomodule.cpython-32.so
33n/a*/
34n/a
35n/aconst char *_PyImport_DynLoadFiletab[] = {
36n/a#ifdef __CYGWIN__
37n/a ".dll",
38n/a#else /* !__CYGWIN__ */
39n/a "." SOABI ".so",
40n/a ".abi" PYTHON_ABI_STRING ".so",
41n/a ".so",
42n/a#endif /* __CYGWIN__ */
43n/a NULL,
44n/a};
45n/a
46n/astatic struct {
47n/a dev_t dev;
48n/a ino_t ino;
49n/a void *handle;
50n/a} handles[128];
51n/astatic int nhandles = 0;
52n/a
53n/a
54n/adl_funcptr
55n/a_PyImport_FindSharedFuncptr(const char *prefix,
56n/a const char *shortname,
57n/a const char *pathname, FILE *fp)
58n/a{
59n/a dl_funcptr p;
60n/a void *handle;
61n/a char funcname[258];
62n/a char pathbuf[260];
63n/a int dlopenflags=0;
64n/a
65n/a if (strchr(pathname, '/') == NULL) {
66n/a /* Prefix bare filename with "./" */
67n/a PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
68n/a pathname = pathbuf;
69n/a }
70n/a
71n/a PyOS_snprintf(funcname, sizeof(funcname),
72n/a LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname);
73n/a
74n/a if (fp != NULL) {
75n/a int i;
76n/a struct _Py_stat_struct status;
77n/a if (_Py_fstat(fileno(fp), &status) == -1)
78n/a return NULL;
79n/a for (i = 0; i < nhandles; i++) {
80n/a if (status.st_dev == handles[i].dev &&
81n/a status.st_ino == handles[i].ino) {
82n/a p = (dl_funcptr) dlsym(handles[i].handle,
83n/a funcname);
84n/a return p;
85n/a }
86n/a }
87n/a if (nhandles < 128) {
88n/a handles[nhandles].dev = status.st_dev;
89n/a handles[nhandles].ino = status.st_ino;
90n/a }
91n/a }
92n/a
93n/a dlopenflags = PyThreadState_GET()->interp->dlopenflags;
94n/a
95n/a handle = dlopen(pathname, dlopenflags);
96n/a
97n/a if (handle == NULL) {
98n/a PyObject *mod_name;
99n/a PyObject *path;
100n/a PyObject *error_ob;
101n/a const char *error = dlerror();
102n/a if (error == NULL)
103n/a error = "unknown dlopen() error";
104n/a error_ob = PyUnicode_FromString(error);
105n/a if (error_ob == NULL)
106n/a return NULL;
107n/a mod_name = PyUnicode_FromString(shortname);
108n/a if (mod_name == NULL) {
109n/a Py_DECREF(error_ob);
110n/a return NULL;
111n/a }
112n/a path = PyUnicode_FromString(pathname);
113n/a if (path == NULL) {
114n/a Py_DECREF(error_ob);
115n/a Py_DECREF(mod_name);
116n/a return NULL;
117n/a }
118n/a PyErr_SetImportError(error_ob, mod_name, path);
119n/a Py_DECREF(error_ob);
120n/a Py_DECREF(mod_name);
121n/a Py_DECREF(path);
122n/a return NULL;
123n/a }
124n/a if (fp != NULL && nhandles < 128)
125n/a handles[nhandles++].handle = handle;
126n/a p = (dl_funcptr) dlsym(handle, funcname);
127n/a return p;
128n/a}