source: python/trunk/Modules/getpath.c@ 10

Last change on this file since 10 was 10, checked in by Yuri Dario, 15 years ago

python: merged offline changes.

  • Property svn:eol-style set to native
File size: 21.1 KB
Line 
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 * Modules/Setup. 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
94#ifdef __cplusplus
95 extern "C" {
96#endif
97
98
99#ifndef VERSION
100#define VERSION "2.1"
101#endif
102
103#ifndef VPATH
104#define VPATH "."
105#endif
106
107#ifndef PREFIX
108# ifdef __VMS
109# define PREFIX ""
110# else
111# define PREFIX "/usr/local"
112# endif
113#endif
114
115#ifndef EXEC_PREFIX
116#define EXEC_PREFIX PREFIX
117#endif
118
119#ifndef __EMX__
120#ifndef PYTHONPATH
121#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
122 EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
123#endif
124#else
125//#define PYTHONPATH "./Lib;./Lib/plat-" PLATFORM \
126// ";./Lib/lib-dynload;./Lib/site-packages"
127// force unixroot
128#define PYTHONPATH PREFIX "/lib/python" VERSION ";" \
129 EXEC_PREFIX "/lib/python" VERSION "/lib-" PLATFORM ";" \
130 EXEC_PREFIX "/lib/python" VERSION "/site-packages" ";" \
131 EXEC_PREFIX "/lib/python" VERSION "/lib-dynload" ";" \
132/* now local (for building) */ \
133 "./lib" ";" \
134 "./lib/plat-" PLATFORM ";" \
135 "./lib/site-packages" ";" \
136 "./lib/lib-dynload"
137#endif
138
139#ifndef LANDMARK
140#define LANDMARK "os.py"
141#endif
142
143static char prefix[MAXPATHLEN+1];
144static char exec_prefix[MAXPATHLEN+1];
145static char progpath[MAXPATHLEN+1];
146static char *module_search_path = NULL;
147static char lib_python[] = "lib/python" VERSION;
148
149static void
150reduce(char *dir)
151{
152 size_t i = strlen(dir);
153 while (i > 0 && !IS_SEP(dir[i]))
154 --i;
155 dir[i] = '\0';
156}
157
158
159static int
160isfile(char *filename) /* Is file, not directory */
161{
162 struct stat buf;
163 if (stat(filename, &buf) != 0)
164 return 0;
165 if (!S_ISREG(buf.st_mode))
166 return 0;
167 return 1;
168}
169
170
171static int
172ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
173{
174 if (isfile(filename))
175 return 1;
176
177 /* Check for the compiled version of prefix. */
178 if (strlen(filename) < MAXPATHLEN) {
179 strcat(filename, Py_OptimizeFlag ? "o" : "c");
180 if (isfile(filename))
181 return 1;
182 }
183 return 0;
184}
185
186
187static int
188isxfile(char *filename) /* Is executable file */
189{
190 struct stat buf;
191 if (stat(filename, &buf) != 0)
192 return 0;
193 if (!S_ISREG(buf.st_mode))
194 return 0;
195 if ((buf.st_mode & 0111) == 0)
196 return 0;
197 return 1;
198}
199
200
201static int
202isdir(char *filename) /* Is directory */
203{
204 struct stat buf;
205 if (stat(filename, &buf) != 0)
206 return 0;
207 if (!S_ISDIR(buf.st_mode))
208 return 0;
209 return 1;
210}
211
212
213/* Add a path component, by appending stuff to buffer.
214 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
215 NUL-terminated string with no more than MAXPATHLEN characters (not counting
216 the trailing NUL). It's a fatal error if it contains a string longer than
217 that (callers must be careful!). If these requirements are met, it's
218 guaranteed that buffer will still be a NUL-terminated string with no more
219 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
220 stuff as fits will be appended.
221*/
222static void
223joinpath(char *buffer, char *stuff)
224{
225 size_t n, k;
226 if (IS_ABSPATH(stuff))
227 n = 0;
228 else {
229 n = strlen(buffer);
230 if (n > 0 && !IS_SEP(buffer[n-1]) && n < MAXPATHLEN)
231 buffer[n++] = SEP;
232 }
233 if (n > MAXPATHLEN)
234 Py_FatalError("buffer overflow in getpath.c's joinpath()");
235 k = strlen(stuff);
236 if (n + k > MAXPATHLEN)
237 k = MAXPATHLEN - n;
238 strncpy(buffer+n, stuff, k);
239 buffer[n+k] = '\0';
240}
241
242/* copy_absolute requires that path be allocated at least
243 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
244static void
245copy_absolute(char *path, char *p)
246{
247 if (IS_ABSPATH(p)) {
248 strcpy(path, p);
249#ifdef ALTSEP
250 p = path;
251 while ((p = strchr(p, ALTSEP)))
252 *p++ = SEP;
253#endif
254 }
255 else {
256 getcwd(path, MAXPATHLEN);
257 if (p[0] == '.' && IS_SEP(p[1]))
258 p += 2;
259 joinpath(path, p);
260 }
261}
262
263/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
264static void
265absolutize(char *path)
266{
267 char buffer[MAXPATHLEN + 1];
268
269 if (IS_ABSPATH(path)) {
270#ifdef ALTSEP
271 while ((path = strchr(path, ALTSEP)))
272 *path++ = SEP;
273#endif
274 return;
275 }
276 copy_absolute(buffer, path);
277 strcpy(path, buffer);
278}
279
280/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
281 bytes long.
282*/
283static int
284search_for_prefix(char *argv0_path, char *home)
285{
286 size_t n;
287 char *vpath;
288
289 /* If PYTHONHOME is set, we believe it unconditionally */
290 if (home) {
291 char *delim;
292 strncpy(prefix, home, MAXPATHLEN);
293 delim = strchr(prefix, DELIM);
294 if (delim)
295 *delim = '\0';
296 joinpath(prefix, lib_python);
297 joinpath(prefix, LANDMARK);
298 return 1;
299 }
300
301 /* Check to see if argv[0] is in the build directory */
302 strcpy(prefix, argv0_path);
303 joinpath(prefix, "Modules/Setup");
304 if (isfile(prefix)) {
305 /* Check VPATH to see if argv0_path is in the build directory. */
306 vpath = VPATH;
307 strcpy(prefix, argv0_path);
308 joinpath(prefix, vpath);
309 joinpath(prefix, "Lib");
310 joinpath(prefix, LANDMARK);
311 if (ismodule(prefix))
312 return -1;
313 }
314
315 /* Search from argv0_path, until root is found */
316 copy_absolute(prefix, argv0_path);
317 do {
318 n = strlen(prefix);
319 joinpath(prefix, lib_python);
320 joinpath(prefix, LANDMARK);
321 if (ismodule(prefix))
322 return 1;
323 prefix[n] = '\0';
324 reduce(prefix);
325 } while (prefix[0]);
326
327 /* Look at configure's PREFIX */
328 strncpy(prefix, PREFIX, MAXPATHLEN);
329 joinpath(prefix, lib_python);
330 joinpath(prefix, LANDMARK);
331 if (ismodule(prefix))
332 return 1;
333
334 /* Fail */
335 return 0;
336}
337
338
339/* search_for_exec_prefix requires that argv0_path be no more than
340 MAXPATHLEN bytes long.
341*/
342static int
343search_for_exec_prefix(char *argv0_path, char *home)
344{
345 size_t n;
346
347 /* If PYTHONHOME is set, we believe it unconditionally */
348 if (home) {
349 char *delim;
350 delim = strchr(home, DELIM);
351 if (delim)
352 strncpy(exec_prefix, delim+1, MAXPATHLEN);
353 else
354 strncpy(exec_prefix, home, MAXPATHLEN);
355 joinpath(exec_prefix, lib_python);
356 joinpath(exec_prefix, "lib-dynload");
357 return 1;
358 }
359
360 /* Check to see if argv[0] is in the build directory */
361 strcpy(exec_prefix, argv0_path);
362 joinpath(exec_prefix, "Modules/Setup");
363 if (isfile(exec_prefix)) {
364 reduce(exec_prefix);
365 return -1;
366 }
367
368 /* Search from argv0_path, until root is found */
369 copy_absolute(exec_prefix, argv0_path);
370 do {
371 n = strlen(exec_prefix);
372 joinpath(exec_prefix, lib_python);
373 joinpath(exec_prefix, "lib-dynload");
374 if (isdir(exec_prefix))
375 return 1;
376 exec_prefix[n] = '\0';
377 reduce(exec_prefix);
378 } while (exec_prefix[0]);
379
380 /* Look at configure's EXEC_PREFIX */
381 strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
382 joinpath(exec_prefix, lib_python);
383 joinpath(exec_prefix, "lib-dynload");
384 if (isdir(exec_prefix))
385 return 1;
386
387 /* Fail */
388 return 0;
389}
390
391
392static void
393calculate_path(void)
394{
395 extern char *Py_GetProgramName(void);
396
397 static char delimiter[2] = {DELIM, '\0'};
398 static char separator[2] = {SEP, '\0'};
399 char *pythonpath = PYTHONPATH;
400 char *rtpypath = Py_GETENV("PYTHONPATH");
401 char *home = Py_GetPythonHome();
402 char *path = getenv("PATH");
403 char *prog = Py_GetProgramName();
404 char argv0_path[MAXPATHLEN+1];
405 char zip_path[MAXPATHLEN+1];
406 int pfound, efound; /* 1 if found; -1 if found build directory */
407 char *buf;
408 size_t bufsz;
409 size_t prefixsz;
410 char *defpath = pythonpath;
411#ifdef WITH_NEXT_FRAMEWORK
412 NSModule pythonModule;
413#endif
414#ifdef __APPLE__
415#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
416 uint32_t nsexeclength = MAXPATHLEN;
417#else
418 unsigned long nsexeclength = MAXPATHLEN;
419#endif
420#endif
421
422 /* If there is no slash in the argv0 path, then we have to
423 * assume python is on the user's $PATH, since there's no
424 * other way to find a directory to start the search from. If
425 * $PATH isn't exported, you lose.
426 */
427 if (HAS_ANYSEP(prog))
428 strncpy(progpath, prog, MAXPATHLEN);
429#ifdef __APPLE__
430 /* On Mac OS X, if a script uses an interpreter of the form
431 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
432 * as argv[0], which falls through to the $PATH search below.
433 * If /opt/python2.3/bin isn't in your path, or is near the end,
434 * this algorithm may incorrectly find /usr/bin/python. To work
435 * around this, we can use _NSGetExecutablePath to get a better
436 * hint of what the intended interpreter was, although this
437 * will fail if a relative path was used. but in that case,
438 * absolutize() should help us out below
439 */
440 else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
441 ;
442#endif /* __APPLE__ */
443 else if (path) {
444 while (1) {
445 char *delim = strchr(path, DELIM);
446
447 if (delim) {
448 size_t len = delim - path;
449 if (len > MAXPATHLEN)
450 len = MAXPATHLEN;
451 strncpy(progpath, path, len);
452 *(progpath + len) = '\0';
453 }
454 else
455 strncpy(progpath, path, MAXPATHLEN);
456
457 joinpath(progpath, prog);
458 if (isxfile(progpath))
459 break;
460
461 if (!delim) {
462 progpath[0] = '\0';
463 break;
464 }
465 path = delim + 1;
466 }
467 }
468 else
469 progpath[0] = '\0';
470#ifndef ALTSEP
471 if (!IS_ABSPATH(progpath))
472#endif
473 absolutize(progpath);
474 strncpy(argv0_path, progpath, MAXPATHLEN);
475 argv0_path[MAXPATHLEN] = '\0';
476
477#ifdef WITH_NEXT_FRAMEWORK
478 /* On Mac OS X we have a special case if we're running from a framework.
479 ** This is because the python home should be set relative to the library,
480 ** which is in the framework, not relative to the executable, which may
481 ** be outside of the framework. Except when we're in the build directory...
482 */
483 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
484 /* Use dylib functions to find out where the framework was loaded from */
485 buf = (char *)NSLibraryNameForModule(pythonModule);
486 if (buf != NULL) {
487 /* We're in a framework. */
488 /* See if we might be in the build directory. The framework in the
489 ** build directory is incomplete, it only has the .dylib and a few
490 ** needed symlinks, it doesn't have the Lib directories and such.
491 ** If we're running with the framework from the build directory we must
492 ** be running the interpreter in the build directory, so we use the
493 ** build-directory-specific logic to find Lib and such.
494 */
495 strncpy(argv0_path, buf, MAXPATHLEN);
496 reduce(argv0_path);
497 joinpath(argv0_path, lib_python);
498 joinpath(argv0_path, LANDMARK);
499 if (!ismodule(argv0_path)) {
500 /* We are in the build directory so use the name of the
501 executable - we know that the absolute path is passed */
502 strncpy(argv0_path, prog, MAXPATHLEN);
503 }
504 else {
505 /* Use the location of the library as the progpath */
506 strncpy(argv0_path, buf, MAXPATHLEN);
507 }
508 }
509#endif
510
511#if HAVE_READLINK
512 {
513 char tmpbuffer[MAXPATHLEN+1];
514 int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
515 while (linklen != -1) {
516 /* It's not null terminated! */
517 tmpbuffer[linklen] = '\0';
518 if (IS_ABSPATH(tmpbuffer))
519 /* tmpbuffer should never be longer than MAXPATHLEN,
520 but extra check does not hurt */
521 strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
522 else {
523 /* Interpret relative to progpath */
524 reduce(argv0_path);
525 joinpath(argv0_path, tmpbuffer);
526 }
527 linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
528 }
529 }
530#endif /* HAVE_READLINK */
531
532 reduce(argv0_path);
533 /* At this point, argv0_path is guaranteed to be less than
534 MAXPATHLEN bytes long.
535 */
536
537 if (!(pfound = search_for_prefix(argv0_path, home))) {
538 if (!Py_FrozenFlag)
539 fprintf(stderr,
540 "Could not find platform independent libraries <prefix>\n");
541 strncpy(prefix, PREFIX, MAXPATHLEN);
542 joinpath(prefix, lib_python);
543 }
544 else
545 reduce(prefix);
546
547 strncpy(zip_path, prefix, MAXPATHLEN);
548 zip_path[MAXPATHLEN] = '\0';
549 if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
550 reduce(zip_path);
551 reduce(zip_path);
552 }
553 else
554 strncpy(zip_path, PREFIX, MAXPATHLEN);
555 joinpath(zip_path, "lib/python00.zip");
556 bufsz = strlen(zip_path); /* Replace "00" with version */
557 zip_path[bufsz - 6] = VERSION[0];
558 zip_path[bufsz - 5] = VERSION[2];
559
560 if (!(efound = search_for_exec_prefix(argv0_path, home))) {
561 if (!Py_FrozenFlag)
562 fprintf(stderr,
563 "Could not find platform dependent libraries <exec_prefix>\n");
564 strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
565 joinpath(exec_prefix, "lib/lib-dynload");
566 }
567 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
568
569 if ((!pfound || !efound) && !Py_FrozenFlag)
570 fprintf(stderr,
571 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
572
573 /* Calculate size of return buffer.
574 */
575 bufsz = 0;
576
577 if (rtpypath)
578 bufsz += strlen(rtpypath) + 1;
579
580 prefixsz = strlen(prefix) + 1;
581
582 while (1) {
583 char *delim = strchr(defpath, ':'); /* bird: hardcoded DELIM in default path. */
584
585 if (!IS_ABSPATH(defpath))
586 /* Paths are relative to prefix */
587 bufsz += prefixsz;
588
589 if (delim)
590 bufsz += delim - defpath + 1;
591 else {
592 bufsz += strlen(defpath) + 1;
593 break;
594 }
595 defpath = delim + 1;
596 }
597
598 bufsz += strlen(zip_path) + 1;
599 bufsz += strlen(exec_prefix) + 1;
600
601 /* This is the only malloc call in this file */
602 buf = (char *)PyMem_Malloc(bufsz);
603
604 if (buf == NULL) {
605 /* We can't exit, so print a warning and limp along */
606 fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
607 fprintf(stderr, "Using default static PYTHONPATH.\n");
608 module_search_path = PYTHONPATH;
609 }
610 else {
611 /* Run-time value of $PYTHONPATH goes first */
612 if (rtpypath) {
613 strcpy(buf, rtpypath);
614 strcat(buf, delimiter);
615 }
616 else
617 buf[0] = '\0';
618
619 /* Next is the default zip path */
620 strcat(buf, zip_path);
621 strcat(buf, delimiter);
622
623 /* Next goes merge of compile-time $PYTHONPATH with
624 * dynamically located prefix.
625 */
626 defpath = pythonpath;
627 while (1) {
628 char *delim = strchr(defpath, ':'); /* bird: hardcoded DELIM in default path. */
629
630 if (!IS_ABSPATH(defpath)) {
631 strcat(buf, prefix);
632 strcat(buf, separator);
633 }
634
635 if (delim) {
636 size_t len = delim - defpath;
637 size_t end = strlen(buf) + len;
638 strncat(buf, defpath, len);
639 *(buf + end) = DELIM; /* bird: correct the DELIM char. */
640 *(buf + end + 1) = '\0';
641 }
642 else {
643 strcat(buf, defpath);
644 break;
645 }
646 defpath = delim + 1;
647 }
648 strcat(buf, delimiter);
649
650 /* Finally, on goes the directory for dynamic-load modules */
651 strcat(buf, exec_prefix);
652
653 /* And publish the results */
654 module_search_path = buf;
655 }
656
657 /* Reduce prefix and exec_prefix to their essence,
658 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
659 * If we're loading relative to the build directory,
660 * return the compiled-in defaults instead.
661 */
662 if (pfound > 0) {
663 reduce(prefix);
664 reduce(prefix);
665 /* The prefix is the root directory, but reduce() chopped
666 * off the "/". */
667 if (!prefix[0])
668 strcpy(prefix, separator);
669 }
670 else
671 strncpy(prefix, PREFIX, MAXPATHLEN);
672
673 if (efound > 0) {
674 reduce(exec_prefix);
675 reduce(exec_prefix);
676 reduce(exec_prefix);
677 if (!exec_prefix[0])
678 strcpy(exec_prefix, separator);
679 }
680 else
681 strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
682}
683
684
685/* External interface */
686
687char *
688Py_GetPath(void)
689{
690 if (!module_search_path)
691 calculate_path();
692 return module_search_path;
693}
694
695char *
696Py_GetPrefix(void)
697{
698 if (!module_search_path)
699 calculate_path();
700 return prefix;
701}
702
703char *
704Py_GetExecPrefix(void)
705{
706 if (!module_search_path)
707 calculate_path();
708 return exec_prefix;
709}
710
711char *
712Py_GetProgramFullPath(void)
713{
714 if (!module_search_path)
715 calculate_path();
716 return progpath;
717}
718
719
720#ifdef __cplusplus
721}
722#endif
723
Note: See TracBrowser for help on using the repository browser.