Move setting of ioready 'wait' earlier in call chain, to
[python/dscho.git] / Python / dynload_mac.c
blob6b50b168f7e964318189f6b18b46b6d78a9cfed0
2 /* Support for dynamic loading of extension modules */
4 #include "Python.h"
5 #include "importdl.h"
7 #include <Aliases.h>
8 #include <CodeFragments.h>
9 #ifdef USE_GUSI1
10 #include "TFileSpec.h" /* for Path2FSSpec() */
11 #endif
12 #include <Files.h>
13 #include <TextUtils.h>
14 #include "macdefs.h"
15 #include "macglue.h"
18 const struct filedescr _PyImport_DynLoadFiletab[] = {
19 {".slb", "rb", C_EXTENSION},
20 {".carbon.slb", "rb", C_EXTENSION},
21 {0, 0}
25 dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
26 const char *pathname, FILE *fp)
28 dl_funcptr p;
29 char funcname[258];
32 ** Dynamic loading of CFM shared libraries on the Mac. The
33 ** code has become more convoluted than it was, because we
34 ** want to be able to put multiple modules in a single
35 ** file. For this reason, we have to determine the fragment
36 ** name, and we cannot use the library entry point but we have
37 ** to locate the correct init routine "by hand".
39 FSSpec libspec;
40 CFragConnectionID connID;
41 Ptr mainAddr;
42 Str255 errMessage;
43 OSErr err;
44 #ifndef USE_GUSI1
45 Boolean isfolder, didsomething;
46 #endif
47 char buf[512];
48 Str63 fragname;
49 Ptr symAddr;
50 CFragSymbolClass class;
52 /* First resolve any aliases to find the real file */
53 #ifdef USE_GUSI1
54 err = Path2FSSpec(pathname, &libspec);
55 #else
56 c2pstrcpy((unsigned char *)buf, pathname);
57 (void)FSMakeFSSpec(0, 0, (unsigned char *)buf, &libspec);
58 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
59 #endif
60 if ( err ) {
61 PyOS_snprintf(buf, sizeof(buf),
62 "%.200s: %.200s", pathname, PyMac_StrError(err));
63 PyErr_SetString(PyExc_ImportError, buf);
64 return NULL;
66 /* Next, determine the fragment name,
67 by stripping '.slb' and 'module' */
68 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
69 fragname[0] = libspec.name[0];
70 if( strncmp((char *)(fragname+1+fragname[0]-4),
71 ".slb", 4) == 0 )
72 fragname[0] -= 4;
73 if ( strncmp((char *)(fragname+1+fragname[0]-6),
74 "module", 6) == 0 )
75 fragname[0] -= 6;
76 /* Load the fragment
77 (or return the connID if it is already loaded */
78 err = GetDiskFragment(&libspec, 0, 0, fragname,
79 kLoadCFrag, &connID, &mainAddr,
80 errMessage);
81 if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) {
83 ** Special-case code: if PythonCore is too old or too new this means
84 ** the dynamic module was meant for a different Python.
86 if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) {
87 PyOS_snprintf(buf, sizeof(buf),
88 "Dynamic module was built for %s version of MacPython",
89 (err == cfragImportTooOldErr ? "a newer" : "an older"));
90 PyErr_SetString(PyExc_ImportError, buf);
91 return NULL;
94 if ( err ) {
95 PyOS_snprintf(buf, sizeof(buf), "%.*s: %.200s",
96 errMessage[0], errMessage+1,
97 PyMac_StrError(err));
98 PyErr_SetString(PyExc_ImportError, buf);
99 return NULL;
101 /* Locate the address of the correct init function */
102 PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
103 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
104 if ( err ) {
105 PyOS_snprintf(buf, sizeof(buf), "%s: %.200s",
106 funcname, PyMac_StrError(err));
107 PyErr_SetString(PyExc_ImportError, buf);
108 return NULL;
110 p = (dl_funcptr)symAddr;
112 return p;