view Python/dynload_next.c @ 55611:4d38e51e7cdc 3.1

Merged revisions 74062 via svnmerge from svn+ssh://svn.python.org/python/branches/py3k ................ r74062 | alexandre.vassalotti | 2009-07-17 13:43:26 +0200 (Fr, 17 Jul 2009) | 37 lines Merged revisions 73665,73693,73704-73705,73707,73712-73713,73824 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73665 | alexandre.vassalotti | 2009-06-28 21:01:51 -0400 (Sun, 28 Jun 2009) | 2 lines Update docstrings for sys.getdlopenflags() and sys.setdlopenflags(). ........ r73693 | jesse.noller | 2009-06-29 14:20:34 -0400 (Mon, 29 Jun 2009) | 1 line Bug 5906: add a documentation note for unix daemons vs. multiprocessing daemons ........ r73704 | georg.brandl | 2009-06-30 12:15:43 -0400 (Tue, 30 Jun 2009) | 1 line #6376: fix copy-n-paste oversight. ........ r73705 | georg.brandl | 2009-06-30 12:17:28 -0400 (Tue, 30 Jun 2009) | 1 line #6374: add a bit of explanation about shell=True on Windows. ........ r73707 | georg.brandl | 2009-06-30 12:35:11 -0400 (Tue, 30 Jun 2009) | 1 line #6371: fix link targets. ........ r73712 | ezio.melotti | 2009-06-30 18:51:06 -0400 (Tue, 30 Jun 2009) | 1 line Fixed defaultTestCase -> defaultTestResult ........ r73713 | ezio.melotti | 2009-06-30 18:56:16 -0400 (Tue, 30 Jun 2009) | 1 line Fixed a backslash that was not supposed to be there ........ r73824 | ezio.melotti | 2009-07-03 21:18:08 -0400 (Fri, 03 Jul 2009) | 1 line #6398 typo: versio. -> version. ........ ................
author Georg Brandl <georg@python.org>
date Thu, 13 Aug 2009 11:51:54 +0000
parents 94f64f11fdd0
children cab14be0ada1
line wrap: on
line source


/* Support for dynamic loading of extension modules on Mac OS X
** All references to "NeXT" are for historical reasons.
*/

#include "Python.h"
#include "importdl.h"

#include <mach-o/dyld.h>

const struct filedescr _PyImport_DynLoadFiletab[] = {
	{".so", "rb", C_EXTENSION},
	{"module.so", "rb", C_EXTENSION},
	{0, 0}
};

/*
** Python modules are Mach-O MH_BUNDLE files. The best way to load these
** is each in a private namespace, so you can load, say, a module bar and a
** module foo.bar. If we load everything in the global namespace the two
** initbar() symbols will conflict.
** However, it seems some extension packages depend upon being able to access
** each others' global symbols. There seems to be no way to eat our cake and
** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
** you get.
*/

#ifdef USE_DYLD_GLOBAL_NAMESPACE
#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
#else
#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
	NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
#endif
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
					const char *pathname, FILE *fp)
{
	dl_funcptr p = NULL;
	char funcname[258];
	NSObjectFileImageReturnCode rc;
	NSObjectFileImage image;
	NSModule newModule;
	NSSymbol theSym;
	const char *errString;
	char errBuf[512];

	PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname);

#ifdef USE_DYLD_GLOBAL_NAMESPACE
	if (NSIsSymbolNameDefined(funcname)) {
		theSym = NSLookupAndBindSymbol(funcname);
		p = (dl_funcptr)NSAddressOfSymbol(theSym);
		return p;
	}
#endif
	rc = NSCreateObjectFileImageFromFile(pathname, &image);
	switch(rc) {
		default:
		case NSObjectFileImageFailure:
		case NSObjectFileImageFormat:
			/* for these a message is printed on stderr by dyld */
			errString = "Can't create object file image";
		break;
		case NSObjectFileImageSuccess:
			errString = NULL;
			break;
		case NSObjectFileImageInappropriateFile:
			errString = "Inappropriate file type for dynamic loading";
			break;
		case NSObjectFileImageArch:
			errString = "Wrong CPU type in object file";
			break;
		case NSObjectFileImageAccess:
			errString = "Can't read object file (no access)";
			break;
	}
	if (errString == NULL) {
		newModule = NSLinkModule(image, pathname, LINKOPTIONS);
		if (newModule == NULL) {
			int errNo;
			const char *fileName, *moreErrorStr;
			NSLinkEditErrors c;
			NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
			PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s", 
					fileName, moreErrorStr);
			errString = errBuf;
		}
	}
	if (errString != NULL) {
		PyErr_SetString(PyExc_ImportError, errString);
		return NULL;
	}
#ifdef USE_DYLD_GLOBAL_NAMESPACE
	if (!NSIsSymbolNameDefined(funcname)) {
		/* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
		/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
		PyErr_Format(PyExc_ImportError,
				 "Loaded module does not contain symbol %.200s",
				 funcname);
		return NULL;
	}
	theSym = NSLookupAndBindSymbol(funcname);
#else
	theSym = NSLookupSymbolInModule(newModule, funcname);
	if ( theSym == NULL ) {
		/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
		PyErr_Format(PyExc_ImportError,
				 "Loaded module does not contain symbol %.200s",
				 funcname);
		return NULL;
	}
#endif
	p = (dl_funcptr)NSAddressOfSymbol(theSym);
	return p;
}