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