LCOV - code coverage report
Current view: | top level - Python - dynload_shlib.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 10 | 34 | 29.4 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 1 | 1 | 100.0 %
|  |  | Branches: | 3 | 16 | 18.8 %

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

Generated by: LCOV version 1.14