Added 'list_only' option (and modified 'run()' to respect it).
[python/dscho.git] / Modules / getpath.c
blob78b4915fa5ed6a07428b2dc0148b081a3e1bfdb6
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Return the initial module search path. */
34 #include "Python.h"
35 #include "osdefs.h"
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <string.h>
41 #if HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif /* HAVE_UNISTD_H */
45 #ifdef WITH_NEXT_FRAMEWORK
46 #include <mach-o/dyld.h>
47 #endif
49 /* Search in some common locations for the associated Python libraries.
51 * Two directories must be found, the platform independent directory
52 * (prefix), containing the common .py and .pyc files, and the platform
53 * dependent directory (exec_prefix), containing the shared library
54 * modules. Note that prefix and exec_prefix can be the same directory,
55 * but for some installations, they are different.
57 * Py_GetPath() carries out separate searches for prefix and exec_prefix.
58 * Each search tries a number of different locations until a ``landmark''
59 * file or directory is found. If no prefix or exec_prefix is found, a
60 * warning message is issued and the preprocessor defined PREFIX and
61 * EXEC_PREFIX are used (even though they will not work); python carries on
62 * as best as is possible, but most imports will fail.
64 * Before any searches are done, the location of the executable is
65 * determined. If argv[0] has one or more slashs in it, it is used
66 * unchanged. Otherwise, it must have been invoked from the shell's path,
67 * so we search $PATH for the named executable and use that. If the
68 * executable was not found on $PATH (or there was no $PATH environment
69 * variable), the original argv[0] string is used.
71 * Next, the executable location is examined to see if it is a symbolic
72 * link. If so, the link is chased (correctly interpreting a relative
73 * pathname if one is found) and the directory of the link target is used.
75 * Finally, argv0_path is set to the directory containing the executable
76 * (i.e. the last component is stripped).
78 * With argv0_path in hand, we perform a number of steps. The same steps
79 * are performed for prefix and for exec_prefix, but with a different
80 * landmark.
82 * Step 1. Are we running python out of the build directory? This is
83 * checked by looking for a different kind of landmark relative to
84 * argv0_path. For prefix, the landmark's path is derived from the VPATH
85 * preprocessor variable (taking into account that its value is almost, but
86 * not quite, what we need). For exec_prefix, the landmark is
87 * Modules/Setup. If the landmark is found, we're done.
89 * For the remaining steps, the prefix landmark will always be
90 * lib/python$VERSION/string.py and the exec_prefix will always be
91 * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
92 * number as supplied by the Makefile. Note that this means that no more
93 * build directory checking is performed; if the first step did not find
94 * the landmarks, the assumption is that python is running from an
95 * installed setup.
97 * Step 2. See if the $PYTHONHOME environment variable points to the
98 * installed location of the Python libraries. If $PYTHONHOME is set, then
99 * it points to prefix and exec_prefix. $PYTHONHOME can be a single
100 * directory, which is used for both, or the prefix and exec_prefix
101 * directories separated by a colon.
103 * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
104 * backtracking up the path until it is exhausted. This is the most common
105 * step to succeed. Note that if prefix and exec_prefix are different,
106 * exec_prefix is more likely to be found; however if exec_prefix is a
107 * subdirectory of prefix, both will be found.
109 * Step 4. Search the directories pointed to by the preprocessor variables
110 * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be
111 * passed in as options to the configure script.
113 * That's it!
115 * Well, almost. Once we have determined prefix and exec_prefix, the
116 * preprocesor variable PYTHONPATH is used to construct a path. Each
117 * relative path on PYTHONPATH is prefixed with prefix. Then the directory
118 * containing the shared library modules is appended. The environment
119 * variable $PYTHONPATH is inserted in front of it all. Finally, the
120 * prefix and exec_prefix globals are tweaked so they reflect the values
121 * expected by other code, by stripping the "lib/python$VERSION/..." stuff
122 * off. If either points to the build directory, the globals are reset to
123 * the corresponding preprocessor variables (so sys.prefix will reflect the
124 * installation location, even though sys.path points into the build
125 * directory). This seems to make more sense given that currently the only
126 * known use of sys.prefix and sys.exec_prefix is for the ILU installation
127 * process to find the installed Python tree.
130 #ifndef VERSION
131 #define VERSION "1.5"
132 #endif
134 #ifndef VPATH
135 #define VPATH "."
136 #endif
138 #ifndef PREFIX
139 #define PREFIX "/usr/local"
140 #endif
142 #ifndef EXEC_PREFIX
143 #define EXEC_PREFIX PREFIX
144 #endif
146 #ifndef PYTHONPATH
147 /* I know this isn't K&R C, but the Makefile specifies it anyway */
148 #define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
149 EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
150 #endif
152 #ifndef LANDMARK
153 #define LANDMARK "string.py"
154 #endif
156 static char prefix[MAXPATHLEN+1];
157 static char exec_prefix[MAXPATHLEN+1];
158 static char progpath[MAXPATHLEN+1];
159 static char *module_search_path = NULL;
160 static char lib_python[20]; /* Dynamically set to "lib/python" VERSION */
162 static void
163 reduce(dir)
164 char *dir;
166 int i = strlen(dir);
167 while (i > 0 && dir[i] != SEP)
168 --i;
169 dir[i] = '\0';
173 #ifndef S_ISREG
174 #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
175 #endif
177 #ifndef S_ISDIR
178 #define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
179 #endif
181 static int
182 isfile(filename) /* Is file, not directory */
183 char *filename;
185 struct stat buf;
186 if (stat(filename, &buf) != 0)
187 return 0;
188 if (!S_ISREG(buf.st_mode))
189 return 0;
190 return 1;
194 static int
195 ismodule(filename) /* Is module -- check for .pyc/.pyo too */
196 char *filename;
198 if (isfile(filename))
199 return 1;
201 /* Check for the compiled version of prefix. */
202 if (strlen(filename) < MAXPATHLEN) {
203 strcat(filename, Py_OptimizeFlag ? "o" : "c");
204 if (isfile(filename))
205 return 1;
207 return 0;
211 static int
212 isxfile(filename) /* Is executable file */
213 char *filename;
215 struct stat buf;
216 if (stat(filename, &buf) != 0)
217 return 0;
218 if (!S_ISREG(buf.st_mode))
219 return 0;
220 if ((buf.st_mode & 0111) == 0)
221 return 0;
222 return 1;
226 static int
227 isdir(filename) /* Is directory */
228 char *filename;
230 struct stat buf;
231 if (stat(filename, &buf) != 0)
232 return 0;
233 if (!S_ISDIR(buf.st_mode))
234 return 0;
235 return 1;
239 static void
240 joinpath(buffer, stuff)
241 char *buffer;
242 char *stuff;
244 int n, k;
245 if (stuff[0] == SEP)
246 n = 0;
247 else {
248 n = strlen(buffer);
249 if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
250 buffer[n++] = SEP;
252 k = strlen(stuff);
253 if (n + k > MAXPATHLEN)
254 k = MAXPATHLEN - n;
255 strncpy(buffer+n, stuff, k);
256 buffer[n+k] = '\0';
260 static int
261 search_for_prefix(argv0_path, home)
262 char *argv0_path;
263 char *home;
265 int n;
266 char *vpath;
268 /* Check to see if argv[0] is in the build directory */
269 strcpy(prefix, argv0_path);
270 joinpath(prefix, "Modules/Setup");
271 if (isfile(prefix)) {
272 /* Check VPATH to see if argv0_path is in the build directory.
273 * Complication: the VPATH passed in is relative to the
274 * Modules build directory and points to the Modules source
275 * directory; we need it relative to the build tree and
276 * pointing to the source tree. Solution: chop off a leading
277 * ".." (but only if it's there -- it could be an absolute
278 * path) and chop off the final component (assuming it's
279 * "Modules").
281 vpath = VPATH;
282 if (vpath[0] == '.' && vpath[1] == '.' && vpath[2] == '/')
283 vpath += 3;
284 strcpy(prefix, argv0_path);
285 joinpath(prefix, vpath);
286 reduce(prefix);
287 joinpath(prefix, "Lib");
288 joinpath(prefix, LANDMARK);
289 if (ismodule(prefix))
290 return -1;
293 if (home) {
294 /* Check $PYTHONHOME */
295 char *delim;
296 strcpy(prefix, home);
297 delim = strchr(prefix, DELIM);
298 if (delim)
299 *delim = '\0';
300 joinpath(prefix, lib_python);
301 joinpath(prefix, LANDMARK);
302 if (ismodule(prefix))
303 return 1;
306 /* Search from argv0_path, until root is found */
307 strcpy(prefix, argv0_path);
308 do {
309 n = strlen(prefix);
310 joinpath(prefix, lib_python);
311 joinpath(prefix, LANDMARK);
312 if (ismodule(prefix))
313 return 1;
314 prefix[n] = '\0';
315 reduce(prefix);
316 } while (prefix[0]);
318 /* Look at configure's PREFIX */
319 strcpy(prefix, PREFIX);
320 joinpath(prefix, lib_python);
321 joinpath(prefix, LANDMARK);
322 if (ismodule(prefix))
323 return 1;
325 /* Fail */
326 return 0;
330 static int
331 search_for_exec_prefix(argv0_path, home)
332 char *argv0_path;
333 char *home;
335 int n;
337 /* Check to see if argv[0] is in the build directory */
338 strcpy(exec_prefix, argv0_path);
339 joinpath(exec_prefix, "Modules/Setup");
340 if (isfile(exec_prefix)) {
341 reduce(exec_prefix);
342 return -1;
345 if (home) {
346 /* Check $PYTHONHOME */
347 char *delim;
348 delim = strchr(home, DELIM);
349 if (delim)
350 strcpy(exec_prefix, delim+1);
351 else
352 strcpy(exec_prefix, home);
353 joinpath(exec_prefix, lib_python);
354 joinpath(exec_prefix, "lib-dynload");
355 if (isdir(exec_prefix))
356 return 1;
359 /* Search from argv0_path, until root is found */
360 strcpy(exec_prefix, argv0_path);
361 do {
362 n = strlen(exec_prefix);
363 joinpath(exec_prefix, lib_python);
364 joinpath(exec_prefix, "lib-dynload");
365 if (isdir(exec_prefix))
366 return 1;
367 exec_prefix[n] = '\0';
368 reduce(exec_prefix);
369 } while (exec_prefix[0]);
371 /* Look at configure's EXEC_PREFIX */
372 strcpy(exec_prefix, EXEC_PREFIX);
373 joinpath(exec_prefix, lib_python);
374 joinpath(exec_prefix, "lib-dynload");
375 if (isdir(exec_prefix))
376 return 1;
378 /* Fail */
379 return 0;
383 static void
384 calculate_path()
386 extern char *Py_GetProgramName();
388 static char delimiter[2] = {DELIM, '\0'};
389 static char separator[2] = {SEP, '\0'};
390 char *pythonpath = PYTHONPATH;
391 char *rtpypath = getenv("PYTHONPATH");
392 char *home = Py_GetPythonHome();
393 char *path = getenv("PATH");
394 char *prog = Py_GetProgramName();
395 char argv0_path[MAXPATHLEN+1];
396 int pfound, efound; /* 1 if found; -1 if found build directory */
397 char *buf;
398 int bufsz;
399 int prefixsz;
400 char *defpath = pythonpath;
401 #ifdef WITH_NEXT_FRAMEWORK
402 NSModule pythonModule;
403 #endif
405 #ifdef WITH_NEXT_FRAMEWORK
406 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
407 /* Use dylib functions to find out where the framework was loaded from */
408 buf = NSLibraryNameForModule(pythonModule);
409 if (buf != NULL) {
410 /* We're in a framework. */
411 strcpy(progpath, buf);
413 /* Frameworks have support for versioning */
414 strcpy(lib_python, "lib");
415 } else {
416 /* If we're not in a framework, fall back to the old way (even though NSNameOfModule() probably does the same thing.) */
417 #endif
419 /* Initialize this dynamically for K&R C */
420 sprintf(lib_python, "lib/python%s", VERSION);
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.
427 if (strchr(prog, SEP))
428 strcpy(progpath, prog);
429 else if (path) {
430 while (1) {
431 char *delim = strchr(path, DELIM);
433 if (delim) {
434 int len = delim - path;
435 strncpy(progpath, path, len);
436 *(progpath + len) = '\0';
438 else
439 strcpy(progpath, path);
441 joinpath(progpath, prog);
442 if (isxfile(progpath))
443 break;
445 if (!delim) {
446 progpath[0] = '\0';
447 break;
449 path = delim + 1;
452 else
453 progpath[0] = '\0';
454 #ifdef WITH_NEXT_FRAMEWORK
456 #endif
458 strcpy(argv0_path, progpath);
460 #if HAVE_READLINK
462 char tmpbuffer[MAXPATHLEN+1];
463 int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
464 while (linklen != -1) {
465 /* It's not null terminated! */
466 tmpbuffer[linklen] = '\0';
467 if (tmpbuffer[0] == SEP)
468 strcpy(argv0_path, tmpbuffer);
469 else {
470 /* Interpret relative to progpath */
471 reduce(argv0_path);
472 joinpath(argv0_path, tmpbuffer);
474 linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
477 #endif /* HAVE_READLINK */
479 reduce(argv0_path);
481 if (!(pfound = search_for_prefix(argv0_path, home))) {
482 if (!Py_FrozenFlag)
483 fprintf(stderr,
484 "Could not find platform independent libraries <prefix>\n");
485 strcpy(prefix, PREFIX);
486 joinpath(prefix, lib_python);
488 else
489 reduce(prefix);
491 if (!(efound = search_for_exec_prefix(argv0_path, home))) {
492 if (!Py_FrozenFlag)
493 fprintf(stderr,
494 "Could not find platform dependent libraries <exec_prefix>\n");
495 strcpy(exec_prefix, EXEC_PREFIX);
496 joinpath(exec_prefix, "lib/lib-dynload");
498 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
500 if ((!pfound || !efound) && !Py_FrozenFlag)
501 fprintf(stderr,
502 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
504 /* Calculate size of return buffer.
506 bufsz = 0;
508 if (rtpypath)
509 bufsz += strlen(rtpypath) + 1;
511 prefixsz = strlen(prefix) + 1;
513 while (1) {
514 char *delim = strchr(defpath, DELIM);
516 if (defpath[0] != SEP)
517 /* Paths are relative to prefix */
518 bufsz += prefixsz;
520 if (delim)
521 bufsz += delim - defpath + 1;
522 else {
523 bufsz += strlen(defpath) + 1;
524 break;
526 defpath = delim + 1;
529 bufsz += strlen(exec_prefix) + 1;
531 /* This is the only malloc call in this file */
532 buf = malloc(bufsz);
534 if (buf == NULL) {
535 /* We can't exit, so print a warning and limp along */
536 fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
537 fprintf(stderr, "Using default static PYTHONPATH.\n");
538 module_search_path = PYTHONPATH;
540 else {
541 /* Run-time value of $PYTHONPATH goes first */
542 if (rtpypath) {
543 strcpy(buf, rtpypath);
544 strcat(buf, delimiter);
546 else
547 buf[0] = '\0';
549 /* Next goes merge of compile-time $PYTHONPATH with
550 * dynamically located prefix.
552 defpath = pythonpath;
553 while (1) {
554 char *delim = strchr(defpath, DELIM);
556 if (defpath[0] != SEP) {
557 strcat(buf, prefix);
558 strcat(buf, separator);
561 if (delim) {
562 int len = delim - defpath + 1;
563 int end = strlen(buf) + len;
564 strncat(buf, defpath, len);
565 *(buf + end) = '\0';
567 else {
568 strcat(buf, defpath);
569 break;
571 defpath = delim + 1;
573 strcat(buf, delimiter);
575 /* Finally, on goes the directory for dynamic-load modules */
576 strcat(buf, exec_prefix);
578 /* And publish the results */
579 module_search_path = buf;
582 /* Reduce prefix and exec_prefix to their essence,
583 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
584 * If we're loading relative to the build directory,
585 * return the compiled-in defaults instead.
587 if (pfound > 0) {
588 reduce(prefix);
589 reduce(prefix);
591 else
592 strcpy(prefix, PREFIX);
594 if (efound > 0) {
595 reduce(exec_prefix);
596 reduce(exec_prefix);
597 reduce(exec_prefix);
599 else
600 strcpy(exec_prefix, EXEC_PREFIX);
604 /* External interface */
606 char *
607 Py_GetPath()
609 if (!module_search_path)
610 calculate_path();
611 return module_search_path;
614 char *
615 Py_GetPrefix()
617 if (!module_search_path)
618 calculate_path();
619 return prefix;
622 char *
623 Py_GetExecPrefix()
625 if (!module_search_path)
626 calculate_path();
627 return exec_prefix;
630 char *
631 Py_GetProgramFullPath()
633 if (!module_search_path)
634 calculate_path();
635 return progpath;