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