| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Support for dynamic loading of extension modules */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | #include "importdl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							| 
									
										
										
										
											2001-10-18 21:24:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-18 11:45:19 +00:00
										 |  |  | #if defined(__NetBSD__)
 | 
					
						
							|  |  |  | #include <sys/param.h>
 | 
					
						
							|  |  |  | #if (NetBSD < 199712)
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | #include <nlist.h>
 | 
					
						
							|  |  |  | #include <link.h>
 | 
					
						
							|  |  |  | #define dlerror() "error in dynamic linking"
 | 
					
						
							| 
									
										
										
										
											2001-10-18 21:24:04 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #endif /* NetBSD */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | #ifdef HAVE_DLFCN_H
 | 
					
						
							|  |  |  | #include <dlfcn.h>
 | 
					
						
							| 
									
										
										
										
											2002-02-26 11:41:34 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #if defined(PYOS_OS2) && defined(PYCC_GCC)
 | 
					
						
							|  |  |  | #include "dlfcn.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-18 11:45:19 +00:00
										 |  |  | #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
 | 
					
						
							| 
									
										
										
										
											2000-10-25 22:07:45 +00:00
										 |  |  | #define LEAD_UNDERSCORE "_"
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define LEAD_UNDERSCORE ""
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | const struct filedescr _PyImport_DynLoadFiletab[] = { | 
					
						
							| 
									
										
										
										
											2000-10-05 19:24:26 +00:00
										 |  |  | #ifdef __CYGWIN__
 | 
					
						
							|  |  |  | 	{".dll", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											2001-01-10 21:17:27 +00:00
										 |  |  | 	{"module.dll", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											2002-02-26 11:41:34 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #if defined(PYOS_OS2) && defined(PYCC_GCC)
 | 
					
						
							|  |  |  | 	{".pyd", "rb", C_EXTENSION}, | 
					
						
							|  |  |  | 	{".dll", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #ifdef __VMS
 | 
					
						
							|  |  |  |         {".exe", "rb", C_EXTENSION}, | 
					
						
							|  |  |  |         {".EXE", "rb", C_EXTENSION}, | 
					
						
							|  |  |  |         {"module.exe", "rb", C_EXTENSION}, | 
					
						
							|  |  |  |         {"MODULE.EXE", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											2000-10-05 19:24:26 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	{".so", "rb", C_EXTENSION}, | 
					
						
							|  |  |  | 	{"module.so", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											2002-02-26 11:41:34 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2000-10-05 19:24:26 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	{0, 0} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct { | 
					
						
							|  |  |  | 	dev_t dev; | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #ifdef __VMS
 | 
					
						
							|  |  |  | 	ino_t ino[3]; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	ino_t ino; | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	void *handle; | 
					
						
							|  |  |  | } handles[128]; | 
					
						
							|  |  |  | static int nhandles = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 				    const char *pathname, FILE *fp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dl_funcptr p; | 
					
						
							|  |  |  | 	void *handle; | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | 	char funcname[258]; | 
					
						
							|  |  |  | 	char pathbuf[260]; | 
					
						
							| 
									
										
										
										
											2001-07-18 16:17:16 +00:00
										 |  |  |         int dlopenflags=0; | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (strchr(pathname, '/') == NULL) { | 
					
						
							|  |  |  | 		/* Prefix bare filename with "./" */ | 
					
						
							| 
									
										
										
										
											2001-11-28 20:42:20 +00:00
										 |  |  | 		PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | 		pathname = pathbuf; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-28 20:42:20 +00:00
										 |  |  | 	PyOS_snprintf(funcname, sizeof(funcname),  | 
					
						
							|  |  |  | 		      LEAD_UNDERSCORE "init%.200s", shortname); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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); | 
					
						
							|  |  |  | 				return p; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (nhandles < 128) { | 
					
						
							|  |  |  | 			handles[nhandles].dev = statb.st_dev; | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #ifdef __VMS
 | 
					
						
							|  |  |  | 			handles[nhandles].ino[0] = statb.st_ino[0]; | 
					
						
							|  |  |  | 			handles[nhandles].ino[1] = statb.st_ino[1]; | 
					
						
							|  |  |  | 			handles[nhandles].ino[2] = statb.st_ino[2]; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 			handles[nhandles].ino = statb.st_ino; | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-26 11:41:34 +00:00
										 |  |  | #if !(defined(PYOS_OS2) && defined(PYCC_GCC))
 | 
					
						
							| 
									
										
										
										
											2004-03-25 02:16:23 +00:00
										 |  |  |         dlopenflags = PyThreadState_GET()->interp->dlopenflags; | 
					
						
							| 
									
										
										
										
											2002-02-26 11:41:34 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-07-18 16:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	if (Py_VerboseFlag) | 
					
						
							| 
									
										
										
										
											2004-10-03 08:51:35 +00:00
										 |  |  | 		PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,  | 
					
						
							|  |  |  | 				  dlopenflags); | 
					
						
							| 
									
										
										
										
											2001-07-18 16:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #ifdef __VMS
 | 
					
						
							|  |  |  | 	/* VMS currently don't allow a pathname, use a logical name instead */ | 
					
						
							|  |  |  | 	/* Concatenate 'python_module_' and shortname */ | 
					
						
							|  |  |  | 	/* so "import vms.bar" will use the logical python_module_bar */ | 
					
						
							|  |  |  | 	/* As C module use only one name space this is probably not a */ | 
					
						
							|  |  |  | 	/* important limitation */ | 
					
						
							|  |  |  | 	PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",  | 
					
						
							|  |  |  | 		      shortname); | 
					
						
							|  |  |  | 	pathname = pathbuf; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-18 16:17:16 +00:00
										 |  |  | 	handle = dlopen(pathname, dlopenflags); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	if (handle == NULL) { | 
					
						
							| 
									
										
										
										
											2006-01-04 01:30:17 +00:00
										 |  |  | 		const char *error = dlerror(); | 
					
						
							| 
									
										
										
										
											2005-11-09 06:59:35 +00:00
										 |  |  | 		if (error == NULL) | 
					
						
							|  |  |  | 			error = "unknown dlopen() error"; | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ImportError, error); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (fp != NULL && nhandles < 128) | 
					
						
							|  |  |  | 		handles[nhandles++].handle = handle; | 
					
						
							|  |  |  | 	p = (dl_funcptr) dlsym(handle, funcname); | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } |