Showing the changes to sys/src/cmd/python/Python/dynload_shlib.c (1 of 3706 files). Show all
Unified · Split
| @@ -0,0 +1,143 @@ | |||
| 1 | |||
| 2 | /* Support for dynamic loading of extension modules */ | ||
| 3 | |||
| 4 | #include "Python.h" | ||
| 5 | #include "importdl.h" | ||
| 6 | |||
| 7 | #include <sys/types.h> | ||
| 8 | #include <sys/stat.h> | ||
| 9 | |||
| 10 | #if defined(__NetBSD__) | ||
| 11 | #include <sys/param.h> | ||
| 12 | #if (NetBSD < 199712) | ||
| 13 | #include <nlist.h> | ||
| 14 | #include <link.h> | ||
| 15 | #define dlerror() "error in dynamic linking" | ||
| 16 | #endif | ||
| 17 | #endif /* NetBSD */ | ||
| 18 | |||
| 19 | #ifdef HAVE_DLFCN_H | ||
| 20 | #include <dlfcn.h> | ||
| 21 | #else | ||
| 22 | #if defined(PYOS_OS2) && defined(PYCC_GCC) | ||
| 23 | #include "dlfcn.h" | ||
| 24 | #endif | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) | ||
| 28 | #define LEAD_UNDERSCORE "_" | ||
| 29 | #else | ||
| 30 | #define LEAD_UNDERSCORE "" | ||
| 31 | #endif | ||
| 32 | |||
| 33 | |||
| 34 | const struct filedescr _PyImport_DynLoadFiletab[] = { | ||
| 35 | #ifdef __CYGWIN__ | ||
| 36 | {".dll", "rb", C_EXTENSION}, | ||
| 37 | {"module.dll", "rb", C_EXTENSION}, | ||
| 38 | #else | ||
| 39 | #if defined(PYOS_OS2) && defined(PYCC_GCC) | ||
| 40 | {".pyd", "rb", C_EXTENSION}, | ||
| 41 | {".dll", "rb", C_EXTENSION}, | ||
| 42 | #else | ||
| 43 | #ifdef __VMS | ||
| 44 | {".exe", "rb", C_EXTENSION}, | ||
| 45 | {".EXE", "rb", C_EXTENSION}, | ||
| 46 | {"module.exe", "rb", C_EXTENSION}, | ||
| 47 | {"MODULE.EXE", "rb", C_EXTENSION}, | ||
| 48 | #else | ||
| 49 | {".so", "rb", C_EXTENSION}, | ||
| 50 | {"module.so", "rb", C_EXTENSION}, | ||
| 51 | #endif | ||
| 52 | #endif | ||
| 53 | #endif | ||
| 54 | {0, 0} | ||
| 55 | }; | ||
| 56 | |||
| 57 | static struct { | ||
| 58 | dev_t dev; | ||
| 59 | #ifdef __VMS | ||
| 60 | ino_t ino[3]; | ||
| 61 | #else | ||
| 62 | ino_t ino; | ||
| 63 | #endif | ||
| 64 | void *handle; | ||
| 65 | } handles[128]; | ||
| 66 | static int nhandles = 0; | ||
| 67 | |||
| 68 | |||
| 69 | dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, | ||
| 70 | const char *pathname, FILE *fp) | ||
| 71 | { | ||
| 72 | dl_funcptr p; | ||
| 73 | void *handle; | ||
| 74 | char funcname[258]; | ||
| 75 | char pathbuf[260]; | ||
| 76 | int dlopenflags=0; | ||
| 77 | |||
| 78 | if (strchr(pathname, '/') == NULL) { | ||
| 79 | /* Prefix bare filename with "./" */ | ||
| 80 | PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); | ||
| 81 | pathname = pathbuf; | ||
| 82 | } | ||
| 83 | |||
| 84 | PyOS_snprintf(funcname, sizeof(funcname), | ||
| 85 | LEAD_UNDERSCORE "init%.200s", shortname); | ||
| 86 | |||
| 87 | if (fp != NULL) { | ||
| 88 | int i; | ||
| 89 | struct stat statb; | ||
| 90 | fstat(fileno(fp), &statb); | ||
| 91 | for (i = 0; i < nhandles; i++) { | ||
| 92 | if (statb.st_dev == handles[i].dev && | ||
| 93 | statb.st_ino == handles[i].ino) { | ||
| 94 | p = (dl_funcptr) dlsym(handles[i].handle, | ||
| 95 | funcname); | ||
| 96 | return p; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | if (nhandles < 128) { | ||
| 100 | handles[nhandles].dev = statb.st_dev; | ||
| 101 | #ifdef __VMS | ||
| 102 | handles[nhandles].ino[0] = statb.st_ino[0]; | ||
| 103 | handles[nhandles].ino[1] = statb.st_ino[1]; | ||
| 104 | handles[nhandles].ino[2] = statb.st_ino[2]; | ||
| 105 | #else | ||
| 106 | handles[nhandles].ino = statb.st_ino; | ||
| 107 | #endif | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | #if !(defined(PYOS_OS2) && defined(PYCC_GCC)) | ||
| 112 | dlopenflags = PyThreadState_GET()->interp->dlopenflags; | ||
| 113 | #endif | ||
| 114 | |||
| 115 | if (Py_VerboseFlag) | ||
| 116 | PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname, | ||
| 117 | dlopenflags); | ||
| 118 | |||
| 119 | #ifdef __VMS | ||
| 120 | /* VMS currently don't allow a pathname, use a logical name instead */ | ||
| 121 | /* Concatenate 'python_module_' and shortname */ | ||
| 122 | /* so "import vms.bar" will use the logical python_module_bar */ | ||
| 123 | /* As C module use only one name space this is probably not a */ | ||
| 124 | /* important limitation */ | ||
| 125 | PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s", | ||
| 126 | shortname); | ||
| 127 | pathname = pathbuf; | ||
| 128 | #endif | ||
| 129 | |||
| 130 | handle = dlopen(pathname, dlopenflags); | ||
| 131 | |||
| 132 | if (handle == NULL) { | ||
| 133 | const char *error = dlerror(); | ||
| 134 | if (error == NULL) | ||
| 135 | error = "unknown dlopen() error"; | ||
| 136 | PyErr_SetString(PyExc_ImportError, error); | ||
| 137 | return NULL; | ||
| 138 | } | ||
| 139 | if (fp != NULL && nhandles < 128) | ||
| 140 | handles[nhandles++].handle = handle; | ||
| 141 | p = (dl_funcptr) dlsym(handle, funcname); | ||
| 142 | return p; | ||
| 143 | } | ||