ยปCore Development>Code coverage>Modules/getpath.c

Python code coverage for Modules/getpath.c

#countcontent
1n/a/* Return the initial module search path. */
2n/a
3n/a#include "Python.h"
4n/a#include "osdefs.h"
5n/a
6n/a#include <sys/types.h>
7n/a#include <string.h>
8n/a
9n/a#ifdef __APPLE__
10n/a#include <mach-o/dyld.h>
11n/a#endif
12n/a
13n/a/* Search in some common locations for the associated Python libraries.
14n/a *
15n/a * Two directories must be found, the platform independent directory
16n/a * (prefix), containing the common .py and .pyc files, and the platform
17n/a * dependent directory (exec_prefix), containing the shared library
18n/a * modules. Note that prefix and exec_prefix can be the same directory,
19n/a * but for some installations, they are different.
20n/a *
21n/a * Py_GetPath() carries out separate searches for prefix and exec_prefix.
22n/a * Each search tries a number of different locations until a ``landmark''
23n/a * file or directory is found. If no prefix or exec_prefix is found, a
24n/a * warning message is issued and the preprocessor defined PREFIX and
25n/a * EXEC_PREFIX are used (even though they will not work); python carries on
26n/a * as best as is possible, but most imports will fail.
27n/a *
28n/a * Before any searches are done, the location of the executable is
29n/a * determined. If argv[0] has one or more slashes in it, it is used
30n/a * unchanged. Otherwise, it must have been invoked from the shell's path,
31n/a * so we search $PATH for the named executable and use that. If the
32n/a * executable was not found on $PATH (or there was no $PATH environment
33n/a * variable), the original argv[0] string is used.
34n/a *
35n/a * Next, the executable location is examined to see if it is a symbolic
36n/a * link. If so, the link is chased (correctly interpreting a relative
37n/a * pathname if one is found) and the directory of the link target is used.
38n/a *
39n/a * Finally, argv0_path is set to the directory containing the executable
40n/a * (i.e. the last component is stripped).
41n/a *
42n/a * With argv0_path in hand, we perform a number of steps. The same steps
43n/a * are performed for prefix and for exec_prefix, but with a different
44n/a * landmark.
45n/a *
46n/a * Step 1. Are we running python out of the build directory? This is
47n/a * checked by looking for a different kind of landmark relative to
48n/a * argv0_path. For prefix, the landmark's path is derived from the VPATH
49n/a * preprocessor variable (taking into account that its value is almost, but
50n/a * not quite, what we need). For exec_prefix, the landmark is
51n/a * pybuilddir.txt. If the landmark is found, we're done.
52n/a *
53n/a * For the remaining steps, the prefix landmark will always be
54n/a * lib/python$VERSION/os.py and the exec_prefix will always be
55n/a * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
56n/a * number as supplied by the Makefile. Note that this means that no more
57n/a * build directory checking is performed; if the first step did not find
58n/a * the landmarks, the assumption is that python is running from an
59n/a * installed setup.
60n/a *
61n/a * Step 2. See if the $PYTHONHOME environment variable points to the
62n/a * installed location of the Python libraries. If $PYTHONHOME is set, then
63n/a * it points to prefix and exec_prefix. $PYTHONHOME can be a single
64n/a * directory, which is used for both, or the prefix and exec_prefix
65n/a * directories separated by a colon.
66n/a *
67n/a * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
68n/a * backtracking up the path until it is exhausted. This is the most common
69n/a * step to succeed. Note that if prefix and exec_prefix are different,
70n/a * exec_prefix is more likely to be found; however if exec_prefix is a
71n/a * subdirectory of prefix, both will be found.
72n/a *
73n/a * Step 4. Search the directories pointed to by the preprocessor variables
74n/a * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be
75n/a * passed in as options to the configure script.
76n/a *
77n/a * That's it!
78n/a *
79n/a * Well, almost. Once we have determined prefix and exec_prefix, the
80n/a * preprocessor variable PYTHONPATH is used to construct a path. Each
81n/a * relative path on PYTHONPATH is prefixed with prefix. Then the directory
82n/a * containing the shared library modules is appended. The environment
83n/a * variable $PYTHONPATH is inserted in front of it all. Finally, the
84n/a * prefix and exec_prefix globals are tweaked so they reflect the values
85n/a * expected by other code, by stripping the "lib/python$VERSION/..." stuff
86n/a * off. If either points to the build directory, the globals are reset to
87n/a * the corresponding preprocessor variables (so sys.prefix will reflect the
88n/a * installation location, even though sys.path points into the build
89n/a * directory). This seems to make more sense given that currently the only
90n/a * known use of sys.prefix and sys.exec_prefix is for the ILU installation
91n/a * process to find the installed Python tree.
92n/a *
93n/a * An embedding application can use Py_SetPath() to override all of
94n/a * these authomatic path computations.
95n/a *
96n/a * NOTE: Windows MSVC builds use PC/getpathp.c instead!
97n/a */
98n/a
99n/a#ifdef __cplusplus
100n/a extern "C" {
101n/a#endif
102n/a
103n/a
104n/a#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH)
105n/a#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined"
106n/a#endif
107n/a
108n/a#ifndef LANDMARK
109n/a#define LANDMARK L"os.py"
110n/a#endif
111n/a
112n/astatic wchar_t prefix[MAXPATHLEN+1];
113n/astatic wchar_t exec_prefix[MAXPATHLEN+1];
114n/astatic wchar_t progpath[MAXPATHLEN+1];
115n/astatic wchar_t *module_search_path = NULL;
116n/a
117n/a/* Get file status. Encode the path to the locale encoding. */
118n/a
119n/astatic int
120n/a_Py_wstat(const wchar_t* path, struct stat *buf)
121n/a{
122n/a int err;
123n/a char *fname;
124n/a fname = Py_EncodeLocale(path, NULL);
125n/a if (fname == NULL) {
126n/a errno = EINVAL;
127n/a return -1;
128n/a }
129n/a err = stat(fname, buf);
130n/a PyMem_Free(fname);
131n/a return err;
132n/a}
133n/a
134n/astatic void
135n/areduce(wchar_t *dir)
136n/a{
137n/a size_t i = wcslen(dir);
138n/a while (i > 0 && dir[i] != SEP)
139n/a --i;
140n/a dir[i] = '\0';
141n/a}
142n/a
143n/astatic int
144n/aisfile(wchar_t *filename) /* Is file, not directory */
145n/a{
146n/a struct stat buf;
147n/a if (_Py_wstat(filename, &buf) != 0)
148n/a return 0;
149n/a if (!S_ISREG(buf.st_mode))
150n/a return 0;
151n/a return 1;
152n/a}
153n/a
154n/a
155n/astatic int
156n/aismodule(wchar_t *filename) /* Is module -- check for .pyc too */
157n/a{
158n/a if (isfile(filename))
159n/a return 1;
160n/a
161n/a /* Check for the compiled version of prefix. */
162n/a if (wcslen(filename) < MAXPATHLEN) {
163n/a wcscat(filename, L"c");
164n/a if (isfile(filename))
165n/a return 1;
166n/a }
167n/a return 0;
168n/a}
169n/a
170n/a
171n/astatic int
172n/aisxfile(wchar_t *filename) /* Is executable file */
173n/a{
174n/a struct stat buf;
175n/a if (_Py_wstat(filename, &buf) != 0)
176n/a return 0;
177n/a if (!S_ISREG(buf.st_mode))
178n/a return 0;
179n/a if ((buf.st_mode & 0111) == 0)
180n/a return 0;
181n/a return 1;
182n/a}
183n/a
184n/a
185n/astatic int
186n/aisdir(wchar_t *filename) /* Is directory */
187n/a{
188n/a struct stat buf;
189n/a if (_Py_wstat(filename, &buf) != 0)
190n/a return 0;
191n/a if (!S_ISDIR(buf.st_mode))
192n/a return 0;
193n/a return 1;
194n/a}
195n/a
196n/a
197n/a/* Add a path component, by appending stuff to buffer.
198n/a buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
199n/a NUL-terminated string with no more than MAXPATHLEN characters (not counting
200n/a the trailing NUL). It's a fatal error if it contains a string longer than
201n/a that (callers must be careful!). If these requirements are met, it's
202n/a guaranteed that buffer will still be a NUL-terminated string with no more
203n/a than MAXPATHLEN characters at exit. If stuff is too long, only as much of
204n/a stuff as fits will be appended.
205n/a*/
206n/astatic void
207n/ajoinpath(wchar_t *buffer, wchar_t *stuff)
208n/a{
209n/a size_t n, k;
210n/a if (stuff[0] == SEP)
211n/a n = 0;
212n/a else {
213n/a n = wcslen(buffer);
214n/a if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
215n/a buffer[n++] = SEP;
216n/a }
217n/a if (n > MAXPATHLEN)
218n/a Py_FatalError("buffer overflow in getpath.c's joinpath()");
219n/a k = wcslen(stuff);
220n/a if (n + k > MAXPATHLEN)
221n/a k = MAXPATHLEN - n;
222n/a wcsncpy(buffer+n, stuff, k);
223n/a buffer[n+k] = '\0';
224n/a}
225n/a
226n/a/* copy_absolute requires that path be allocated at least
227n/a MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
228n/astatic void
229n/acopy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
230n/a{
231n/a if (p[0] == SEP)
232n/a wcscpy(path, p);
233n/a else {
234n/a if (!_Py_wgetcwd(path, pathlen)) {
235n/a /* unable to get the current directory */
236n/a wcscpy(path, p);
237n/a return;
238n/a }
239n/a if (p[0] == '.' && p[1] == SEP)
240n/a p += 2;
241n/a joinpath(path, p);
242n/a }
243n/a}
244n/a
245n/a/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
246n/astatic void
247n/aabsolutize(wchar_t *path)
248n/a{
249n/a wchar_t buffer[MAXPATHLEN+1];
250n/a
251n/a if (path[0] == SEP)
252n/a return;
253n/a copy_absolute(buffer, path, MAXPATHLEN+1);
254n/a wcscpy(path, buffer);
255n/a}
256n/a
257n/a/* search for a prefix value in an environment file. If found, copy it
258n/a to the provided buffer, which is expected to be no more than MAXPATHLEN
259n/a bytes long.
260n/a*/
261n/a
262n/astatic int
263n/afind_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
264n/a{
265n/a int result = 0; /* meaning not found */
266n/a char buffer[MAXPATHLEN*2+1]; /* allow extra for key, '=', etc. */
267n/a
268n/a fseek(env_file, 0, SEEK_SET);
269n/a while (!feof(env_file)) {
270n/a char * p = fgets(buffer, MAXPATHLEN*2, env_file);
271n/a wchar_t tmpbuffer[MAXPATHLEN*2+1];
272n/a PyObject * decoded;
273n/a int n;
274n/a
275n/a if (p == NULL)
276n/a break;
277n/a n = strlen(p);
278n/a if (p[n - 1] != '\n') {
279n/a /* line has overflowed - bail */
280n/a break;
281n/a }
282n/a if (p[0] == '#') /* Comment - skip */
283n/a continue;
284n/a decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
285n/a if (decoded != NULL) {
286n/a Py_ssize_t k;
287n/a wchar_t * state;
288n/a k = PyUnicode_AsWideChar(decoded,
289n/a tmpbuffer, MAXPATHLEN * 2);
290n/a Py_DECREF(decoded);
291n/a if (k >= 0) {
292n/a wchar_t * tok = wcstok(tmpbuffer, L" \t\r\n", &state);
293n/a if ((tok != NULL) && !wcscmp(tok, key)) {
294n/a tok = wcstok(NULL, L" \t", &state);
295n/a if ((tok != NULL) && !wcscmp(tok, L"=")) {
296n/a tok = wcstok(NULL, L"\r\n", &state);
297n/a if (tok != NULL) {
298n/a wcsncpy(value, tok, MAXPATHLEN);
299n/a result = 1;
300n/a break;
301n/a }
302n/a }
303n/a }
304n/a }
305n/a }
306n/a }
307n/a return result;
308n/a}
309n/a
310n/a/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
311n/a bytes long.
312n/a*/
313n/astatic int
314n/asearch_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix,
315n/a wchar_t *lib_python)
316n/a{
317n/a size_t n;
318n/a wchar_t *vpath;
319n/a
320n/a /* If PYTHONHOME is set, we believe it unconditionally */
321n/a if (home) {
322n/a wchar_t *delim;
323n/a wcsncpy(prefix, home, MAXPATHLEN);
324n/a prefix[MAXPATHLEN] = L'\0';
325n/a delim = wcschr(prefix, DELIM);
326n/a if (delim)
327n/a *delim = L'\0';
328n/a joinpath(prefix, lib_python);
329n/a joinpath(prefix, LANDMARK);
330n/a return 1;
331n/a }
332n/a
333n/a /* Check to see if argv[0] is in the build directory */
334n/a wcsncpy(prefix, argv0_path, MAXPATHLEN);
335n/a prefix[MAXPATHLEN] = L'\0';
336n/a joinpath(prefix, L"Modules/Setup");
337n/a if (isfile(prefix)) {
338n/a /* Check VPATH to see if argv0_path is in the build directory. */
339n/a vpath = Py_DecodeLocale(VPATH, NULL);
340n/a if (vpath != NULL) {
341n/a wcsncpy(prefix, argv0_path, MAXPATHLEN);
342n/a prefix[MAXPATHLEN] = L'\0';
343n/a joinpath(prefix, vpath);
344n/a PyMem_RawFree(vpath);
345n/a joinpath(prefix, L"Lib");
346n/a joinpath(prefix, LANDMARK);
347n/a if (ismodule(prefix))
348n/a return -1;
349n/a }
350n/a }
351n/a
352n/a /* Search from argv0_path, until root is found */
353n/a copy_absolute(prefix, argv0_path, MAXPATHLEN+1);
354n/a do {
355n/a n = wcslen(prefix);
356n/a joinpath(prefix, lib_python);
357n/a joinpath(prefix, LANDMARK);
358n/a if (ismodule(prefix))
359n/a return 1;
360n/a prefix[n] = L'\0';
361n/a reduce(prefix);
362n/a } while (prefix[0]);
363n/a
364n/a /* Look at configure's PREFIX */
365n/a wcsncpy(prefix, _prefix, MAXPATHLEN);
366n/a prefix[MAXPATHLEN] = L'\0';
367n/a joinpath(prefix, lib_python);
368n/a joinpath(prefix, LANDMARK);
369n/a if (ismodule(prefix))
370n/a return 1;
371n/a
372n/a /* Fail */
373n/a return 0;
374n/a}
375n/a
376n/a
377n/a/* search_for_exec_prefix requires that argv0_path be no more than
378n/a MAXPATHLEN bytes long.
379n/a*/
380n/astatic int
381n/asearch_for_exec_prefix(wchar_t *argv0_path, wchar_t *home,
382n/a wchar_t *_exec_prefix, wchar_t *lib_python)
383n/a{
384n/a size_t n;
385n/a
386n/a /* If PYTHONHOME is set, we believe it unconditionally */
387n/a if (home) {
388n/a wchar_t *delim;
389n/a delim = wcschr(home, DELIM);
390n/a if (delim)
391n/a wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
392n/a else
393n/a wcsncpy(exec_prefix, home, MAXPATHLEN);
394n/a exec_prefix[MAXPATHLEN] = L'\0';
395n/a joinpath(exec_prefix, lib_python);
396n/a joinpath(exec_prefix, L"lib-dynload");
397n/a return 1;
398n/a }
399n/a
400n/a /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
401n/a is written by setup.py and contains the relative path to the location
402n/a of shared library modules. */
403n/a wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
404n/a exec_prefix[MAXPATHLEN] = L'\0';
405n/a joinpath(exec_prefix, L"pybuilddir.txt");
406n/a if (isfile(exec_prefix)) {
407n/a FILE *f = _Py_wfopen(exec_prefix, L"rb");
408n/a if (f == NULL)
409n/a errno = 0;
410n/a else {
411n/a char buf[MAXPATHLEN+1];
412n/a PyObject *decoded;
413n/a wchar_t rel_builddir_path[MAXPATHLEN+1];
414n/a n = fread(buf, 1, MAXPATHLEN, f);
415n/a buf[n] = '\0';
416n/a fclose(f);
417n/a decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
418n/a if (decoded != NULL) {
419n/a Py_ssize_t k;
420n/a k = PyUnicode_AsWideChar(decoded,
421n/a rel_builddir_path, MAXPATHLEN);
422n/a Py_DECREF(decoded);
423n/a if (k >= 0) {
424n/a rel_builddir_path[k] = L'\0';
425n/a wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
426n/a exec_prefix[MAXPATHLEN] = L'\0';
427n/a joinpath(exec_prefix, rel_builddir_path);
428n/a return -1;
429n/a }
430n/a }
431n/a }
432n/a }
433n/a
434n/a /* Search from argv0_path, until root is found */
435n/a copy_absolute(exec_prefix, argv0_path, MAXPATHLEN+1);
436n/a do {
437n/a n = wcslen(exec_prefix);
438n/a joinpath(exec_prefix, lib_python);
439n/a joinpath(exec_prefix, L"lib-dynload");
440n/a if (isdir(exec_prefix))
441n/a return 1;
442n/a exec_prefix[n] = L'\0';
443n/a reduce(exec_prefix);
444n/a } while (exec_prefix[0]);
445n/a
446n/a /* Look at configure's EXEC_PREFIX */
447n/a wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
448n/a exec_prefix[MAXPATHLEN] = L'\0';
449n/a joinpath(exec_prefix, lib_python);
450n/a joinpath(exec_prefix, L"lib-dynload");
451n/a if (isdir(exec_prefix))
452n/a return 1;
453n/a
454n/a /* Fail */
455n/a return 0;
456n/a}
457n/a
458n/astatic void
459n/acalculate_path(void)
460n/a{
461n/a extern wchar_t *Py_GetProgramName(void);
462n/a
463n/a static const wchar_t delimiter[2] = {DELIM, '\0'};
464n/a static const wchar_t separator[2] = {SEP, '\0'};
465n/a char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */
466n/a wchar_t *rtpypath = NULL;
467n/a wchar_t *home = Py_GetPythonHome();
468n/a char *_path = getenv("PATH");
469n/a wchar_t *path_buffer = NULL;
470n/a wchar_t *path = NULL;
471n/a wchar_t *prog = Py_GetProgramName();
472n/a wchar_t argv0_path[MAXPATHLEN+1];
473n/a wchar_t zip_path[MAXPATHLEN+1];
474n/a int pfound, efound; /* 1 if found; -1 if found build directory */
475n/a wchar_t *buf;
476n/a size_t bufsz;
477n/a size_t prefixsz;
478n/a wchar_t *defpath;
479n/a#ifdef WITH_NEXT_FRAMEWORK
480n/a NSModule pythonModule;
481n/a const char* modPath;
482n/a#endif
483n/a#ifdef __APPLE__
484n/a#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
485n/a uint32_t nsexeclength = MAXPATHLEN;
486n/a#else
487n/a unsigned long nsexeclength = MAXPATHLEN;
488n/a#endif
489n/a char execpath[MAXPATHLEN+1];
490n/a#endif
491n/a wchar_t *_pythonpath, *_prefix, *_exec_prefix;
492n/a wchar_t *lib_python;
493n/a
494n/a _pythonpath = Py_DecodeLocale(PYTHONPATH, NULL);
495n/a _prefix = Py_DecodeLocale(PREFIX, NULL);
496n/a _exec_prefix = Py_DecodeLocale(EXEC_PREFIX, NULL);
497n/a lib_python = Py_DecodeLocale("lib/python" VERSION, NULL);
498n/a
499n/a if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) {
500n/a Py_FatalError(
501n/a "Unable to decode path variables in getpath.c: "
502n/a "memory error");
503n/a }
504n/a
505n/a if (_path) {
506n/a path_buffer = Py_DecodeLocale(_path, NULL);
507n/a path = path_buffer;
508n/a }
509n/a
510n/a /* If there is no slash in the argv0 path, then we have to
511n/a * assume python is on the user's $PATH, since there's no
512n/a * other way to find a directory to start the search from. If
513n/a * $PATH isn't exported, you lose.
514n/a */
515n/a if (wcschr(prog, SEP))
516n/a wcsncpy(progpath, prog, MAXPATHLEN);
517n/a#ifdef __APPLE__
518n/a /* On Mac OS X, if a script uses an interpreter of the form
519n/a * "#!/opt/python2.3/bin/python", the kernel only passes "python"
520n/a * as argv[0], which falls through to the $PATH search below.
521n/a * If /opt/python2.3/bin isn't in your path, or is near the end,
522n/a * this algorithm may incorrectly find /usr/bin/python. To work
523n/a * around this, we can use _NSGetExecutablePath to get a better
524n/a * hint of what the intended interpreter was, although this
525n/a * will fail if a relative path was used. but in that case,
526n/a * absolutize() should help us out below
527n/a */
528n/a else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) {
529n/a size_t r = mbstowcs(progpath, execpath, MAXPATHLEN+1);
530n/a if (r == (size_t)-1 || r > MAXPATHLEN) {
531n/a /* Could not convert execpath, or it's too long. */
532n/a progpath[0] = '\0';
533n/a }
534n/a }
535n/a#endif /* __APPLE__ */
536n/a else if (path) {
537n/a while (1) {
538n/a wchar_t *delim = wcschr(path, DELIM);
539n/a
540n/a if (delim) {
541n/a size_t len = delim - path;
542n/a if (len > MAXPATHLEN)
543n/a len = MAXPATHLEN;
544n/a wcsncpy(progpath, path, len);
545n/a *(progpath + len) = '\0';
546n/a }
547n/a else
548n/a wcsncpy(progpath, path, MAXPATHLEN);
549n/a
550n/a joinpath(progpath, prog);
551n/a if (isxfile(progpath))
552n/a break;
553n/a
554n/a if (!delim) {
555n/a progpath[0] = L'\0';
556n/a break;
557n/a }
558n/a path = delim + 1;
559n/a }
560n/a }
561n/a else
562n/a progpath[0] = '\0';
563n/a PyMem_RawFree(path_buffer);
564n/a if (progpath[0] != SEP && progpath[0] != '\0')
565n/a absolutize(progpath);
566n/a wcsncpy(argv0_path, progpath, MAXPATHLEN);
567n/a argv0_path[MAXPATHLEN] = '\0';
568n/a
569n/a#ifdef WITH_NEXT_FRAMEWORK
570n/a /* On Mac OS X we have a special case if we're running from a framework.
571n/a ** This is because the python home should be set relative to the library,
572n/a ** which is in the framework, not relative to the executable, which may
573n/a ** be outside of the framework. Except when we're in the build directory...
574n/a */
575n/a pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
576n/a /* Use dylib functions to find out where the framework was loaded from */
577n/a modPath = NSLibraryNameForModule(pythonModule);
578n/a if (modPath != NULL) {
579n/a /* We're in a framework. */
580n/a /* See if we might be in the build directory. The framework in the
581n/a ** build directory is incomplete, it only has the .dylib and a few
582n/a ** needed symlinks, it doesn't have the Lib directories and such.
583n/a ** If we're running with the framework from the build directory we must
584n/a ** be running the interpreter in the build directory, so we use the
585n/a ** build-directory-specific logic to find Lib and such.
586n/a */
587n/a wchar_t* wbuf = Py_DecodeLocale(modPath, NULL);
588n/a if (wbuf == NULL) {
589n/a Py_FatalError("Cannot decode framework location");
590n/a }
591n/a
592n/a wcsncpy(argv0_path, wbuf, MAXPATHLEN);
593n/a reduce(argv0_path);
594n/a joinpath(argv0_path, lib_python);
595n/a joinpath(argv0_path, LANDMARK);
596n/a if (!ismodule(argv0_path)) {
597n/a /* We are in the build directory so use the name of the
598n/a executable - we know that the absolute path is passed */
599n/a wcsncpy(argv0_path, progpath, MAXPATHLEN);
600n/a }
601n/a else {
602n/a /* Use the location of the library as the progpath */
603n/a wcsncpy(argv0_path, wbuf, MAXPATHLEN);
604n/a }
605n/a PyMem_RawFree(wbuf);
606n/a }
607n/a#endif
608n/a
609n/a#if HAVE_READLINK
610n/a {
611n/a wchar_t tmpbuffer[MAXPATHLEN+1];
612n/a int linklen = _Py_wreadlink(progpath, tmpbuffer, MAXPATHLEN);
613n/a while (linklen != -1) {
614n/a if (tmpbuffer[0] == SEP)
615n/a /* tmpbuffer should never be longer than MAXPATHLEN,
616n/a but extra check does not hurt */
617n/a wcsncpy(argv0_path, tmpbuffer, MAXPATHLEN);
618n/a else {
619n/a /* Interpret relative to progpath */
620n/a reduce(argv0_path);
621n/a joinpath(argv0_path, tmpbuffer);
622n/a }
623n/a linklen = _Py_wreadlink(argv0_path, tmpbuffer, MAXPATHLEN);
624n/a }
625n/a }
626n/a#endif /* HAVE_READLINK */
627n/a
628n/a reduce(argv0_path);
629n/a /* At this point, argv0_path is guaranteed to be less than
630n/a MAXPATHLEN bytes long.
631n/a */
632n/a
633n/a /* Search for an environment configuration file, first in the
634n/a executable's directory and then in the parent directory.
635n/a If found, open it for use when searching for prefixes.
636n/a */
637n/a
638n/a {
639n/a wchar_t tmpbuffer[MAXPATHLEN+1];
640n/a wchar_t *env_cfg = L"pyvenv.cfg";
641n/a FILE * env_file = NULL;
642n/a
643n/a wcscpy(tmpbuffer, argv0_path);
644n/a
645n/a joinpath(tmpbuffer, env_cfg);
646n/a env_file = _Py_wfopen(tmpbuffer, L"r");
647n/a if (env_file == NULL) {
648n/a errno = 0;
649n/a reduce(tmpbuffer);
650n/a reduce(tmpbuffer);
651n/a joinpath(tmpbuffer, env_cfg);
652n/a env_file = _Py_wfopen(tmpbuffer, L"r");
653n/a if (env_file == NULL) {
654n/a errno = 0;
655n/a }
656n/a }
657n/a if (env_file != NULL) {
658n/a /* Look for a 'home' variable and set argv0_path to it, if found */
659n/a if (find_env_config_value(env_file, L"home", tmpbuffer)) {
660n/a wcscpy(argv0_path, tmpbuffer);
661n/a }
662n/a fclose(env_file);
663n/a env_file = NULL;
664n/a }
665n/a }
666n/a
667n/a pfound = search_for_prefix(argv0_path, home, _prefix, lib_python);
668n/a if (!pfound) {
669n/a if (!Py_FrozenFlag)
670n/a fprintf(stderr,
671n/a "Could not find platform independent libraries <prefix>\n");
672n/a wcsncpy(prefix, _prefix, MAXPATHLEN);
673n/a joinpath(prefix, lib_python);
674n/a }
675n/a else
676n/a reduce(prefix);
677n/a
678n/a wcsncpy(zip_path, prefix, MAXPATHLEN);
679n/a zip_path[MAXPATHLEN] = L'\0';
680n/a if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
681n/a reduce(zip_path);
682n/a reduce(zip_path);
683n/a }
684n/a else
685n/a wcsncpy(zip_path, _prefix, MAXPATHLEN);
686n/a joinpath(zip_path, L"lib/python00.zip");
687n/a bufsz = wcslen(zip_path); /* Replace "00" with version */
688n/a zip_path[bufsz - 6] = VERSION[0];
689n/a zip_path[bufsz - 5] = VERSION[2];
690n/a
691n/a efound = search_for_exec_prefix(argv0_path, home,
692n/a _exec_prefix, lib_python);
693n/a if (!efound) {
694n/a if (!Py_FrozenFlag)
695n/a fprintf(stderr,
696n/a "Could not find platform dependent libraries <exec_prefix>\n");
697n/a wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
698n/a joinpath(exec_prefix, L"lib/lib-dynload");
699n/a }
700n/a /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
701n/a
702n/a if ((!pfound || !efound) && !Py_FrozenFlag)
703n/a fprintf(stderr,
704n/a "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
705n/a
706n/a /* Calculate size of return buffer.
707n/a */
708n/a bufsz = 0;
709n/a
710n/a if (_rtpypath && _rtpypath[0] != '\0') {
711n/a size_t rtpypath_len;
712n/a rtpypath = Py_DecodeLocale(_rtpypath, &rtpypath_len);
713n/a if (rtpypath != NULL)
714n/a bufsz += rtpypath_len + 1;
715n/a }
716n/a
717n/a defpath = _pythonpath;
718n/a prefixsz = wcslen(prefix) + 1;
719n/a while (1) {
720n/a wchar_t *delim = wcschr(defpath, DELIM);
721n/a
722n/a if (defpath[0] != SEP)
723n/a /* Paths are relative to prefix */
724n/a bufsz += prefixsz;
725n/a
726n/a if (delim)
727n/a bufsz += delim - defpath + 1;
728n/a else {
729n/a bufsz += wcslen(defpath) + 1;
730n/a break;
731n/a }
732n/a defpath = delim + 1;
733n/a }
734n/a
735n/a bufsz += wcslen(zip_path) + 1;
736n/a bufsz += wcslen(exec_prefix) + 1;
737n/a
738n/a buf = PyMem_New(wchar_t, bufsz);
739n/a if (buf == NULL) {
740n/a Py_FatalError(
741n/a "Not enough memory for dynamic PYTHONPATH");
742n/a }
743n/a
744n/a /* Run-time value of $PYTHONPATH goes first */
745n/a if (rtpypath) {
746n/a wcscpy(buf, rtpypath);
747n/a wcscat(buf, delimiter);
748n/a }
749n/a else
750n/a buf[0] = '\0';
751n/a
752n/a /* Next is the default zip path */
753n/a wcscat(buf, zip_path);
754n/a wcscat(buf, delimiter);
755n/a
756n/a /* Next goes merge of compile-time $PYTHONPATH with
757n/a * dynamically located prefix.
758n/a */
759n/a defpath = _pythonpath;
760n/a while (1) {
761n/a wchar_t *delim = wcschr(defpath, DELIM);
762n/a
763n/a if (defpath[0] != SEP) {
764n/a wcscat(buf, prefix);
765n/a if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
766n/a defpath[0] != (delim ? DELIM : L'\0')) { /* not empty */
767n/a wcscat(buf, separator);
768n/a }
769n/a }
770n/a
771n/a if (delim) {
772n/a size_t len = delim - defpath + 1;
773n/a size_t end = wcslen(buf) + len;
774n/a wcsncat(buf, defpath, len);
775n/a *(buf + end) = '\0';
776n/a }
777n/a else {
778n/a wcscat(buf, defpath);
779n/a break;
780n/a }
781n/a defpath = delim + 1;
782n/a }
783n/a wcscat(buf, delimiter);
784n/a
785n/a /* Finally, on goes the directory for dynamic-load modules */
786n/a wcscat(buf, exec_prefix);
787n/a
788n/a /* And publish the results */
789n/a module_search_path = buf;
790n/a
791n/a /* Reduce prefix and exec_prefix to their essence,
792n/a * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
793n/a * If we're loading relative to the build directory,
794n/a * return the compiled-in defaults instead.
795n/a */
796n/a if (pfound > 0) {
797n/a reduce(prefix);
798n/a reduce(prefix);
799n/a /* The prefix is the root directory, but reduce() chopped
800n/a * off the "/". */
801n/a if (!prefix[0])
802n/a wcscpy(prefix, separator);
803n/a }
804n/a else
805n/a wcsncpy(prefix, _prefix, MAXPATHLEN);
806n/a
807n/a if (efound > 0) {
808n/a reduce(exec_prefix);
809n/a reduce(exec_prefix);
810n/a reduce(exec_prefix);
811n/a if (!exec_prefix[0])
812n/a wcscpy(exec_prefix, separator);
813n/a }
814n/a else
815n/a wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
816n/a
817n/a PyMem_RawFree(_pythonpath);
818n/a PyMem_RawFree(_prefix);
819n/a PyMem_RawFree(_exec_prefix);
820n/a PyMem_RawFree(lib_python);
821n/a PyMem_RawFree(rtpypath);
822n/a}
823n/a
824n/a
825n/a/* External interface */
826n/avoid
827n/aPy_SetPath(const wchar_t *path)
828n/a{
829n/a if (module_search_path != NULL) {
830n/a PyMem_RawFree(module_search_path);
831n/a module_search_path = NULL;
832n/a }
833n/a if (path != NULL) {
834n/a extern wchar_t *Py_GetProgramName(void);
835n/a wchar_t *prog = Py_GetProgramName();
836n/a wcsncpy(progpath, prog, MAXPATHLEN);
837n/a exec_prefix[0] = prefix[0] = L'\0';
838n/a module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
839n/a if (module_search_path != NULL)
840n/a wcscpy(module_search_path, path);
841n/a }
842n/a}
843n/a
844n/awchar_t *
845n/aPy_GetPath(void)
846n/a{
847n/a if (!module_search_path)
848n/a calculate_path();
849n/a return module_search_path;
850n/a}
851n/a
852n/awchar_t *
853n/aPy_GetPrefix(void)
854n/a{
855n/a if (!module_search_path)
856n/a calculate_path();
857n/a return prefix;
858n/a}
859n/a
860n/awchar_t *
861n/aPy_GetExecPrefix(void)
862n/a{
863n/a if (!module_search_path)
864n/a calculate_path();
865n/a return exec_prefix;
866n/a}
867n/a
868n/awchar_t *
869n/aPy_GetProgramFullPath(void)
870n/a{
871n/a if (!module_search_path)
872n/a calculate_path();
873n/a return progpath;
874n/a}
875n/a
876n/a
877n/a#ifdef __cplusplus
878n/a}
879n/a#endif