getpath.c 16.6 KB
Newer Older
1 2 3

/* Return the initial module search path. */

Guido van Rossum's avatar
Guido van Rossum committed
4 5 6
#include "Python.h"
#include "osdefs.h"

7 8
#include <sys/types.h>
#include <sys/stat.h>
9
#include <string.h>
Guido van Rossum's avatar
Guido van Rossum committed
10

11 12 13 14
#if HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */

15 16 17 18
#ifdef WITH_NEXT_FRAMEWORK
#include <mach-o/dyld.h>
#endif

19 20 21
/* Search in some common locations for the associated Python libraries.
 *
 * Two directories must be found, the platform independent directory
22 23 24 25
 * (prefix), containing the common .py and .pyc files, and the platform
 * dependent directory (exec_prefix), containing the shared library
 * modules.  Note that prefix and exec_prefix can be the same directory,
 * but for some installations, they are different.
26
 *
27 28 29 30 31 32
 * Py_GetPath() carries out separate searches for prefix and exec_prefix.
 * Each search tries a number of different locations until a ``landmark''
 * file or directory is found.  If no prefix or exec_prefix is found, a
 * warning message is issued and the preprocessor defined PREFIX and
 * EXEC_PREFIX are used (even though they will not work); python carries on
 * as best as is possible, but most imports will fail.
33 34
 *
 * Before any searches are done, the location of the executable is
35 36 37 38 39
 * determined.  If argv[0] has one or more slashs in it, it is used
 * unchanged.  Otherwise, it must have been invoked from the shell's path,
 * so we search $PATH for the named executable and use that.  If the
 * executable was not found on $PATH (or there was no $PATH environment
 * variable), the original argv[0] string is used.
40
 *
41 42 43
 * Next, the executable location is examined to see if it is a symbolic
 * link.  If so, the link is chased (correctly interpreting a relative
 * pathname if one is found) and the directory of the link target is used.
44
 *
45 46
 * Finally, argv0_path is set to the directory containing the executable
 * (i.e. the last component is stripped).
47
 *
48 49 50
 * With argv0_path in hand, we perform a number of steps.  The same steps
 * are performed for prefix and for exec_prefix, but with a different
 * landmark.
51 52 53
 *
 * Step 1. Are we running python out of the build directory?  This is
 * checked by looking for a different kind of landmark relative to
54 55 56 57
 * argv0_path.  For prefix, the landmark's path is derived from the VPATH
 * preprocessor variable (taking into account that its value is almost, but
 * not quite, what we need).  For exec_prefix, the landmark is
 * Modules/Setup.  If the landmark is found, we're done.
58 59
 *
 * For the remaining steps, the prefix landmark will always be
60
 * lib/python$VERSION/os.py and the exec_prefix will always be
61
 * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
62 63 64 65
 * number as supplied by the Makefile.  Note that this means that no more
 * build directory checking is performed; if the first step did not find
 * the landmarks, the assumption is that python is running from an
 * installed setup.
66 67
 *
 * Step 2. See if the $PYTHONHOME environment variable points to the
68 69 70 71
 * installed location of the Python libraries.  If $PYTHONHOME is set, then
 * it points to prefix and exec_prefix.  $PYTHONHOME can be a single
 * directory, which is used for both, or the prefix and exec_prefix
 * directories separated by a colon.
72 73
 *
 * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
74 75 76 77
 * backtracking up the path until it is exhausted.  This is the most common
 * step to succeed.  Note that if prefix and exec_prefix are different,
 * exec_prefix is more likely to be found; however if exec_prefix is a
 * subdirectory of prefix, both will be found.
78
 *
79 80 81
 * Step 4. Search the directories pointed to by the preprocessor variables
 * PREFIX and EXEC_PREFIX.  These are supplied by the Makefile but can be
 * passed in as options to the configure script.
82
 *
83 84 85
 * That's it!
 *
 * Well, almost.  Once we have determined prefix and exec_prefix, the
86
 * preprocessor variable PYTHONPATH is used to construct a path.  Each
87 88 89 90 91 92 93 94 95 96 97 98
 * relative path on PYTHONPATH is prefixed with prefix.  Then the directory
 * containing the shared library modules is appended.  The environment
 * variable $PYTHONPATH is inserted in front of it all.  Finally, the
 * prefix and exec_prefix globals are tweaked so they reflect the values
 * expected by other code, by stripping the "lib/python$VERSION/..." stuff
 * off.  If either points to the build directory, the globals are reset to
 * the corresponding preprocessor variables (so sys.prefix will reflect the
 * installation location, even though sys.path points into the build
 * directory).  This seems to make more sense given that currently the only
 * known use of sys.prefix and sys.exec_prefix is for the ILU installation
 * process to find the installed Python tree.
 */
99 100 101 102 103 104 105

#ifndef VERSION
#define VERSION "1.5"
#endif

#ifndef VPATH
#define VPATH "."
Guido van Rossum's avatar
Guido van Rossum committed
106 107
#endif

108 109 110 111 112
#ifndef PREFIX
#define PREFIX "/usr/local"
#endif

#ifndef EXEC_PREFIX
113
#define EXEC_PREFIX PREFIX
114 115
#endif

116 117 118
#ifndef PYTHONPATH
/* I know this isn't K&R C, but the Makefile specifies it anyway */
#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
119
	      EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
120
#endif
Guido van Rossum's avatar
Guido van Rossum committed
121

122
#ifndef LANDMARK
123
#define LANDMARK "os.py"
124
#endif
Guido van Rossum's avatar
Guido van Rossum committed
125

126 127
static char prefix[MAXPATHLEN+1];
static char exec_prefix[MAXPATHLEN+1];
128
static char progpath[MAXPATHLEN+1];
129 130 131 132
static char *module_search_path = NULL;
static char lib_python[20]; /* Dynamically set to "lib/python" VERSION */

static void
133
reduce(char *dir)
134
{
135 136 137 138
    size_t i = strlen(dir);
    while (i > 0 && dir[i] != SEP)
        --i;
    dir[i] = '\0';
139
}
140 141 142 143 144 145 146 147 148 149 150


#ifndef S_ISREG
#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
#endif

#ifndef S_ISDIR
#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
#endif

static int
151
isfile(char *filename)		/* Is file, not directory */
152
{
153 154 155 156 157 158
    struct stat buf;
    if (stat(filename, &buf) != 0)
        return 0;
    if (!S_ISREG(buf.st_mode))
        return 0;
    return 1;
159 160 161 162
}


static int
163
ismodule(char *filename)	/* Is module -- check for .pyc/.pyo too */
164
{
165 166 167 168 169 170 171 172 173 174
    if (isfile(filename))
        return 1;

    /* Check for the compiled version of prefix. */
    if (strlen(filename) < MAXPATHLEN) {
        strcat(filename, Py_OptimizeFlag ? "o" : "c");
        if (isfile(filename))
            return 1;
    }
    return 0;
175 176 177 178
}


static int
179
isxfile(char *filename)		/* Is executable file */
180
{
181 182 183 184 185 186 187 188
    struct stat buf;
    if (stat(filename, &buf) != 0)
        return 0;
    if (!S_ISREG(buf.st_mode))
        return 0;
    if ((buf.st_mode & 0111) == 0)
        return 0;
    return 1;
189 190
}

191 192

static int
193
isdir(char *filename)			/* Is directory */
194
{
195 196 197 198 199 200
    struct stat buf;
    if (stat(filename, &buf) != 0)
        return 0;
    if (!S_ISDIR(buf.st_mode))
        return 0;
    return 1;
201 202 203 204
}


static void
205
joinpath(char *buffer, char *stuff)
206
{
207 208 209 210 211 212 213 214 215 216 217 218 219
    size_t n, k;
    if (stuff[0] == SEP)
        n = 0;
    else {
        n = strlen(buffer);
        if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
            buffer[n++] = SEP;
    }
    k = strlen(stuff);
    if (n + k > MAXPATHLEN)
        k = MAXPATHLEN - n;
    strncpy(buffer+n, stuff, k);
    buffer[n+k] = '\0';
220 221 222 223
}


static int
224
search_for_prefix(char *argv0_path, char *home)
225
{
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
    size_t n;
    char *vpath;

    /* If PYTHONHOME is set, we believe it unconditionally */
    if (home) {
        char *delim;
        strcpy(prefix, home);
        delim = strchr(prefix, DELIM);
        if (delim)
            *delim = '\0';
        joinpath(prefix, lib_python);
        joinpath(prefix, LANDMARK);
        return 1;
    }

    /* Check to see if argv[0] is in the build directory */
    strcpy(prefix, argv0_path);
    joinpath(prefix, "Modules/Setup");
    if (isfile(prefix)) {
        /* Check VPATH to see if argv0_path is in the build directory.
         * Complication: the VPATH passed in is relative to the
         * Modules build directory and points to the Modules source
         * directory; we need it relative to the build tree and
         * pointing to the source tree.  Solution: chop off a leading
         * ".." (but only if it's there -- it could be an absolute
         * path) and chop off the final component (assuming it's
         * "Modules").
         */
        vpath = VPATH;
        if (vpath[0] == '.' && vpath[1] == '.' && vpath[2] == '/')
            vpath += 3;
        strcpy(prefix, argv0_path);
        joinpath(prefix, vpath);
        reduce(prefix);
        joinpath(prefix, "Lib");
        joinpath(prefix, LANDMARK);
        if (ismodule(prefix))
            return -1;
    }

    /* Search from argv0_path, until root is found */
    strcpy(prefix, argv0_path);
    do {
        n = strlen(prefix);
        joinpath(prefix, lib_python);
        joinpath(prefix, LANDMARK);
        if (ismodule(prefix))
            return 1;
        prefix[n] = '\0';
        reduce(prefix);
    } while (prefix[0]);

    /* Look at configure's PREFIX */
    strcpy(prefix, PREFIX);
    joinpath(prefix, lib_python);
    joinpath(prefix, LANDMARK);
    if (ismodule(prefix))
        return 1;

    /* Fail */
    return 0;
287 288 289 290
}


static int
291
search_for_exec_prefix(char *argv0_path, char *home)
292
{
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
    size_t n;

    /* If PYTHONHOME is set, we believe it unconditionally */
    if (home) {
        char *delim;
        delim = strchr(home, DELIM);
        if (delim)
            strcpy(exec_prefix, delim+1);
        else
            strcpy(exec_prefix, home);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, "lib-dynload");
        return 1;
    }

    /* Check to see if argv[0] is in the build directory */
    strcpy(exec_prefix, argv0_path);
    joinpath(exec_prefix, "Modules/Setup");
    if (isfile(exec_prefix)) {
        reduce(exec_prefix);
        return -1;
    }

    /* Search from argv0_path, until root is found */
    strcpy(exec_prefix, argv0_path);
    do {
        n = strlen(exec_prefix);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, "lib-dynload");
        if (isdir(exec_prefix))
            return 1;
        exec_prefix[n] = '\0';
        reduce(exec_prefix);
    } while (exec_prefix[0]);

    /* Look at configure's EXEC_PREFIX */
    strcpy(exec_prefix, EXEC_PREFIX);
    joinpath(exec_prefix, lib_python);
    joinpath(exec_prefix, "lib-dynload");
    if (isdir(exec_prefix))
        return 1;

    /* Fail */
    return 0;
337 338 339 340
}


static void
341
calculate_path(void)
Guido van Rossum's avatar
Guido van Rossum committed
342
{
343
    extern char *Py_GetProgramName(void);
344 345 346 347 348 349 350 351 352 353 354 355 356 357

    static char delimiter[2] = {DELIM, '\0'};
    static char separator[2] = {SEP, '\0'};
    char *pythonpath = PYTHONPATH;
    char *rtpypath = getenv("PYTHONPATH");
    char *home = Py_GetPythonHome();
    char *path = getenv("PATH");
    char *prog = Py_GetProgramName();
    char argv0_path[MAXPATHLEN+1];
    int pfound, efound; /* 1 if found; -1 if found build directory */
    char *buf;
    size_t bufsz;
    size_t prefixsz;
    char *defpath = pythonpath;
358
#ifdef WITH_NEXT_FRAMEWORK
359
    NSModule pythonModule;
360 361 362
#endif
	
#ifdef WITH_NEXT_FRAMEWORK
363 364 365 366 367 368 369 370 371 372 373 374 375
    pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
    /* Use dylib functions to find out where the framework was loaded from */
    buf = NSLibraryNameForModule(pythonModule);
    if (buf != NULL) {
        /* We're in a framework. */
        strcpy(progpath, buf);

        /* Frameworks have support for versioning */
        strcpy(lib_python, "lib");
    }
    else {
        /* If we're not in a framework, fall back to the old way
           (even though NSNameOfModule() probably does the same thing.) */
376 377
#endif
	
378 379 380 381 382 383 384 385 386
	/* Initialize this dynamically for K&R C */
	sprintf(lib_python, "lib/python%s", VERSION);

	/* If there is no slash in the argv0 path, then we have to
	 * assume python is on the user's $PATH, since there's no
	 * other way to find a directory to start the search from.  If
	 * $PATH isn't exported, you lose.
	 */
	if (strchr(prog, SEP))
387
            strcpy(progpath, prog);
388
	else if (path) {
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
            while (1) {
                char *delim = strchr(path, DELIM);

                if (delim) {
                    size_t len = delim - path;
                    strncpy(progpath, path, len);
                    *(progpath + len) = '\0';
                }
                else
                    strcpy(progpath, path);

                joinpath(progpath, prog);
                if (isxfile(progpath))
                    break;

                if (!delim) {
                    progpath[0] = '\0';
                    break;
                }
                path = delim + 1;
            }
410 411
	}
	else
412
            progpath[0] = '\0';
413
#ifdef WITH_NEXT_FRAMEWORK
414
    }
415
#endif
416

417
    strcpy(argv0_path, progpath);
418 419
	
#if HAVE_READLINK
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
    {
        char tmpbuffer[MAXPATHLEN+1];
        int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
        while (linklen != -1) {
            /* It's not null terminated! */
            tmpbuffer[linklen] = '\0';
            if (tmpbuffer[0] == SEP)
                strcpy(argv0_path, tmpbuffer);
            else {
                /* Interpret relative to progpath */
                reduce(argv0_path);
                joinpath(argv0_path, tmpbuffer);
            }
            linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
        }
    }
436 437
#endif /* HAVE_READLINK */

438 439 440 441 442 443 444 445 446 447 448
    reduce(argv0_path);

    if (!(pfound = search_for_prefix(argv0_path, home))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                    "Could not find platform independent libraries <prefix>\n");
        strcpy(prefix, PREFIX);
        joinpath(prefix, lib_python);
    }
    else
        reduce(prefix);
449
	
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
    if (!(efound = search_for_exec_prefix(argv0_path, home))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                    "Could not find platform dependent libraries <exec_prefix>\n");
        strcpy(exec_prefix, EXEC_PREFIX);
        joinpath(exec_prefix, "lib/lib-dynload");
    }
    /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */

    if ((!pfound || !efound) && !Py_FrozenFlag)
        fprintf(stderr,
                "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");

    /* Calculate size of return buffer.
     */
    bufsz = 0;

    if (rtpypath)
        bufsz += strlen(rtpypath) + 1;

    prefixsz = strlen(prefix) + 1;

    while (1) {
        char *delim = strchr(defpath, DELIM);

        if (defpath[0] != SEP)
            /* Paths are relative to prefix */
            bufsz += prefixsz;

        if (delim)
            bufsz += delim - defpath + 1;
        else {
            bufsz += strlen(defpath) + 1;
            break;
        }
        defpath = delim + 1;
    }

    bufsz += strlen(exec_prefix) + 1;

    /* This is the only malloc call in this file */
    buf = PyMem_Malloc(bufsz);

    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
        fprintf(stderr, "Using default static PYTHONPATH.\n");
        module_search_path = PYTHONPATH;
    }
    else {
        /* Run-time value of $PYTHONPATH goes first */
        if (rtpypath) {
            strcpy(buf, rtpypath);
            strcat(buf, delimiter);
        }
        else
            buf[0] = '\0';

        /* Next goes merge of compile-time $PYTHONPATH with
         * dynamically located prefix.
         */
        defpath = pythonpath;
        while (1) {
            char *delim = strchr(defpath, DELIM);

            if (defpath[0] != SEP) {
                strcat(buf, prefix);
                strcat(buf, separator);
            }

            if (delim) {
                size_t len = delim - defpath + 1;
                size_t end = strlen(buf) + len;
                strncat(buf, defpath, len);
                *(buf + end) = '\0';
            }
            else {
                strcat(buf, defpath);
                break;
            }
            defpath = delim + 1;
        }
        strcat(buf, delimiter);

        /* Finally, on goes the directory for dynamic-load modules */
        strcat(buf, exec_prefix);

        /* And publish the results */
        module_search_path = buf;
    }

    /* Reduce prefix and exec_prefix to their essence,
     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
     * If we're loading relative to the build directory,
     * return the compiled-in defaults instead.
     */
    if (pfound > 0) {
        reduce(prefix);
        reduce(prefix);
    }
    else
        strcpy(prefix, PREFIX);

    if (efound > 0) {
        reduce(exec_prefix);
        reduce(exec_prefix);
        reduce(exec_prefix);
    }
    else
        strcpy(exec_prefix, EXEC_PREFIX);
Guido van Rossum's avatar
Guido van Rossum committed
560
}
561 562


563 564 565
/* External interface */

char *
566
Py_GetPath(void)
567
{
568 569 570
    if (!module_search_path)
        calculate_path();
    return module_search_path;
571
}
572 573

char *
574
Py_GetPrefix(void)
575
{
576 577 578
    if (!module_search_path)
        calculate_path();
    return prefix;
579 580 581
}

char *
582
Py_GetExecPrefix(void)
583
{
584 585 586
    if (!module_search_path)
        calculate_path();
    return exec_prefix;
587
}
588 589

char *
590
Py_GetProgramFullPath(void)
591
{
592 593 594
    if (!module_search_path)
        calculate_path();
    return progpath;
595
}