blob: 041cb14b4b9c165a191be4bb14b2ffcc28535182 [file] [log] [blame]
Guido van Rossum582646a1996-05-28 22:30:17 +00001/* Return the initial module search path. */
2
Guido van Rossum667d7041995-08-04 04:20:48 +00003#include "Python.h"
Victor Stinnerb64de462017-12-01 18:27:09 +01004#include "internal/pystate.h"
Guido van Rossum667d7041995-08-04 04:20:48 +00005#include "osdefs.h"
6
Guido van Rossum305e5d01997-04-11 17:18:45 +00007#include <sys/types.h>
Guido van Rossum21f84971997-06-02 22:18:31 +00008#include <string.h>
Guido van Rossum667d7041995-08-04 04:20:48 +00009
Brett Cannonf6af76d2004-06-26 04:03:06 +000010#ifdef __APPLE__
Victor Stinner0327bde2017-11-23 17:03:20 +010011# include <mach-o/dyld.h>
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000012#endif
13
Guido van Rossum305e5d01997-04-11 17:18:45 +000014/* Search in some common locations for the associated Python libraries.
15 *
16 * Two directories must be found, the platform independent directory
Barry Warsaw90126031997-04-11 20:27:03 +000017 * (prefix), containing the common .py and .pyc files, and the platform
18 * dependent directory (exec_prefix), containing the shared library
19 * modules. Note that prefix and exec_prefix can be the same directory,
20 * but for some installations, they are different.
Guido van Rossum305e5d01997-04-11 17:18:45 +000021 *
Barry Warsaw90126031997-04-11 20:27:03 +000022 * Py_GetPath() carries out separate searches for prefix and exec_prefix.
23 * Each search tries a number of different locations until a ``landmark''
24 * file or directory is found. If no prefix or exec_prefix is found, a
25 * warning message is issued and the preprocessor defined PREFIX and
26 * EXEC_PREFIX are used (even though they will not work); python carries on
27 * as best as is possible, but most imports will fail.
Guido van Rossum305e5d01997-04-11 17:18:45 +000028 *
29 * Before any searches are done, the location of the executable is
Guido van Rossumd8faa362007-04-27 19:54:29 +000030 * determined. If argv[0] has one or more slashes in it, it is used
Barry Warsaw90126031997-04-11 20:27:03 +000031 * unchanged. Otherwise, it must have been invoked from the shell's path,
32 * so we search $PATH for the named executable and use that. If the
33 * executable was not found on $PATH (or there was no $PATH environment
34 * variable), the original argv[0] string is used.
Guido van Rossum305e5d01997-04-11 17:18:45 +000035 *
Barry Warsaw90126031997-04-11 20:27:03 +000036 * Next, the executable location is examined to see if it is a symbolic
37 * link. If so, the link is chased (correctly interpreting a relative
38 * pathname if one is found) and the directory of the link target is used.
Guido van Rossum305e5d01997-04-11 17:18:45 +000039 *
Barry Warsaw90126031997-04-11 20:27:03 +000040 * Finally, argv0_path is set to the directory containing the executable
41 * (i.e. the last component is stripped).
Guido van Rossum305e5d01997-04-11 17:18:45 +000042 *
Barry Warsaw90126031997-04-11 20:27:03 +000043 * With argv0_path in hand, we perform a number of steps. The same steps
44 * are performed for prefix and for exec_prefix, but with a different
45 * landmark.
Guido van Rossum305e5d01997-04-11 17:18:45 +000046 *
47 * Step 1. Are we running python out of the build directory? This is
48 * checked by looking for a different kind of landmark relative to
Barry Warsaw90126031997-04-11 20:27:03 +000049 * argv0_path. For prefix, the landmark's path is derived from the VPATH
50 * preprocessor variable (taking into account that its value is almost, but
51 * not quite, what we need). For exec_prefix, the landmark is
Antoine Pitroueba57b62010-08-14 12:33:18 +000052 * pybuilddir.txt. If the landmark is found, we're done.
Guido van Rossum305e5d01997-04-11 17:18:45 +000053 *
54 * For the remaining steps, the prefix landmark will always be
Jeremy Hylton847a9962000-05-26 21:49:07 +000055 * lib/python$VERSION/os.py and the exec_prefix will always be
Guido van Rossum266033e1997-10-20 23:20:32 +000056 * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
Barry Warsaw90126031997-04-11 20:27:03 +000057 * number as supplied by the Makefile. Note that this means that no more
58 * build directory checking is performed; if the first step did not find
59 * the landmarks, the assumption is that python is running from an
60 * installed setup.
Guido van Rossum305e5d01997-04-11 17:18:45 +000061 *
62 * Step 2. See if the $PYTHONHOME environment variable points to the
Barry Warsaw90126031997-04-11 20:27:03 +000063 * installed location of the Python libraries. If $PYTHONHOME is set, then
64 * it points to prefix and exec_prefix. $PYTHONHOME can be a single
65 * directory, which is used for both, or the prefix and exec_prefix
66 * directories separated by a colon.
Guido van Rossum305e5d01997-04-11 17:18:45 +000067 *
68 * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
Barry Warsaw90126031997-04-11 20:27:03 +000069 * backtracking up the path until it is exhausted. This is the most common
70 * step to succeed. Note that if prefix and exec_prefix are different,
71 * exec_prefix is more likely to be found; however if exec_prefix is a
72 * subdirectory of prefix, both will be found.
Guido van Rossum305e5d01997-04-11 17:18:45 +000073 *
Barry Warsaw90126031997-04-11 20:27:03 +000074 * Step 4. Search the directories pointed to by the preprocessor variables
75 * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be
76 * passed in as options to the configure script.
Guido van Rossum305e5d01997-04-11 17:18:45 +000077 *
Barry Warsaw90126031997-04-11 20:27:03 +000078 * That's it!
79 *
80 * Well, almost. Once we have determined prefix and exec_prefix, the
Thomas Wouters7e474022000-07-16 12:04:32 +000081 * preprocessor variable PYTHONPATH is used to construct a path. Each
Barry Warsaw90126031997-04-11 20:27:03 +000082 * relative path on PYTHONPATH is prefixed with prefix. Then the directory
83 * containing the shared library modules is appended. The environment
84 * variable $PYTHONPATH is inserted in front of it all. Finally, the
85 * prefix and exec_prefix globals are tweaked so they reflect the values
86 * expected by other code, by stripping the "lib/python$VERSION/..." stuff
87 * off. If either points to the build directory, the globals are reset to
88 * the corresponding preprocessor variables (so sys.prefix will reflect the
89 * installation location, even though sys.path points into the build
90 * directory). This seems to make more sense given that currently the only
91 * known use of sys.prefix and sys.exec_prefix is for the ILU installation
92 * process to find the installed Python tree.
Antoine Pitroueba57b62010-08-14 12:33:18 +000093 *
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +000094 * An embedding application can use Py_SetPath() to override all of
95 * these authomatic path computations.
96 *
Antoine Pitroueba57b62010-08-14 12:33:18 +000097 * NOTE: Windows MSVC builds use PC/getpathp.c instead!
Barry Warsaw90126031997-04-11 20:27:03 +000098 */
Guido van Rossum305e5d01997-04-11 17:18:45 +000099
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000100#ifdef __cplusplus
Victor Stinner0327bde2017-11-23 17:03:20 +0100101extern "C" {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000102#endif
103
104
Benjamin Petersonf5854142016-06-02 12:41:35 -0700105#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH)
106#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined"
Guido van Rossum305e5d01997-04-11 17:18:45 +0000107#endif
Guido van Rossum667d7041995-08-04 04:20:48 +0000108
Guido van Rossum305e5d01997-04-11 17:18:45 +0000109#ifndef LANDMARK
Martin v. Löwis790465f2008-04-05 20:41:37 +0000110#define LANDMARK L"os.py"
Guido van Rossum305e5d01997-04-11 17:18:45 +0000111#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000112
Victor Stinner9316ee42017-11-25 03:17:57 +0100113#define DECODE_LOCALE_ERR(NAME, LEN) \
114 ((LEN) == (size_t)-2) \
Victor Stinner94540602017-12-16 04:54:22 +0100115 ? _Py_INIT_USER_ERR("cannot decode " NAME) \
Victor Stinner9316ee42017-11-25 03:17:57 +0100116 : _Py_INIT_NO_MEMORY()
117
Victor Stinner0327bde2017-11-23 17:03:20 +0100118typedef struct {
119 wchar_t *path_env; /* PATH environment variable */
Victor Stinner0327bde2017-11-23 17:03:20 +0100120
Victor Stinner0327bde2017-11-23 17:03:20 +0100121 wchar_t *pythonpath; /* PYTHONPATH define */
122 wchar_t *prefix; /* PREFIX define */
123 wchar_t *exec_prefix; /* EXEC_PREFIX define */
124
125 wchar_t *lib_python; /* "lib/pythonX.Y" */
126 wchar_t argv0_path[MAXPATHLEN+1];
127 wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */
128
129 int prefix_found; /* found platform independent libraries? */
130 int exec_prefix_found; /* found the platform dependent libraries? */
131} PyCalculatePath;
132
133static const wchar_t delimiter[2] = {DELIM, '\0'};
134static const wchar_t separator[2] = {SEP, '\0'};
Victor Stinner0327bde2017-11-23 17:03:20 +0100135
Martin v. Löwis790465f2008-04-05 20:41:37 +0000136
Victor Stinner91afbb62015-03-24 12:16:28 +0100137/* Get file status. Encode the path to the locale encoding. */
Victor Stinner91afbb62015-03-24 12:16:28 +0100138static int
139_Py_wstat(const wchar_t* path, struct stat *buf)
140{
141 int err;
142 char *fname;
Victor Stinner9dd76202017-12-21 16:20:32 +0100143 fname = _Py_EncodeLocaleRaw(path, NULL);
Victor Stinner91afbb62015-03-24 12:16:28 +0100144 if (fname == NULL) {
145 errno = EINVAL;
146 return -1;
147 }
148 err = stat(fname, buf);
Victor Stinner9dd76202017-12-21 16:20:32 +0100149 PyMem_RawFree(fname);
Victor Stinner91afbb62015-03-24 12:16:28 +0100150 return err;
151}
152
Victor Stinner0327bde2017-11-23 17:03:20 +0100153
Guido van Rossum305e5d01997-04-11 17:18:45 +0000154static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000155reduce(wchar_t *dir)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000156{
Martin v. Löwis790465f2008-04-05 20:41:37 +0000157 size_t i = wcslen(dir);
Fred Drakeedabdc12000-07-08 06:16:37 +0000158 while (i > 0 && dir[i] != SEP)
159 --i;
160 dir[i] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000161}
Guido van Rossumd29806c1998-01-19 22:06:22 +0000162
Victor Stinner0327bde2017-11-23 17:03:20 +0100163
Guido van Rossum305e5d01997-04-11 17:18:45 +0000164static int
Martin v. Löwis790465f2008-04-05 20:41:37 +0000165isfile(wchar_t *filename) /* Is file, not directory */
Guido van Rossum305e5d01997-04-11 17:18:45 +0000166{
Fred Drakeedabdc12000-07-08 06:16:37 +0000167 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100168 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000169 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100170 }
171 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000172 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100173 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000174 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000175}
176
177
178static int
Brett Cannonf299abd2015-04-13 14:21:02 -0400179ismodule(wchar_t *filename) /* Is module -- check for .pyc too */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000180{
Victor Stinner0327bde2017-11-23 17:03:20 +0100181 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000182 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100183 }
Guido van Rossumd29806c1998-01-19 22:06:22 +0000184
Fred Drakeedabdc12000-07-08 06:16:37 +0000185 /* Check for the compiled version of prefix. */
Martin v. Löwis790465f2008-04-05 20:41:37 +0000186 if (wcslen(filename) < MAXPATHLEN) {
Brett Cannonf299abd2015-04-13 14:21:02 -0400187 wcscat(filename, L"c");
Victor Stinner0327bde2017-11-23 17:03:20 +0100188 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000189 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100190 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000191 }
192 return 0;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000193}
194
195
Victor Stinner0327bde2017-11-23 17:03:20 +0100196/* Is executable file */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000197static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100198isxfile(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000199{
Fred Drakeedabdc12000-07-08 06:16:37 +0000200 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100201 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000202 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100203 }
204 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000205 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100206 }
207 if ((buf.st_mode & 0111) == 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000208 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100209 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000210 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000211}
212
213
Victor Stinner0327bde2017-11-23 17:03:20 +0100214/* Is directory */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000215static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100216isdir(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000217{
Fred Drakeedabdc12000-07-08 06:16:37 +0000218 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100219 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000220 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100221 }
222 if (!S_ISDIR(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000223 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100224 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000225 return 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000226}
227
228
Tim Petersec8c5a92004-08-08 01:00:47 +0000229/* Add a path component, by appending stuff to buffer.
230 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
231 NUL-terminated string with no more than MAXPATHLEN characters (not counting
232 the trailing NUL). It's a fatal error if it contains a string longer than
233 that (callers must be careful!). If these requirements are met, it's
234 guaranteed that buffer will still be a NUL-terminated string with no more
235 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
236 stuff as fits will be appended.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000237*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000238static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000239joinpath(wchar_t *buffer, wchar_t *stuff)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000240{
Fred Drakeedabdc12000-07-08 06:16:37 +0000241 size_t n, k;
Victor Stinner0327bde2017-11-23 17:03:20 +0100242 if (stuff[0] == SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000243 n = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100244 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000245 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000246 n = wcslen(buffer);
Victor Stinner0327bde2017-11-23 17:03:20 +0100247 if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000248 buffer[n++] = SEP;
Victor Stinner0327bde2017-11-23 17:03:20 +0100249 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000250 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100251 if (n > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 Py_FatalError("buffer overflow in getpath.c's joinpath()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100253 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000254 k = wcslen(stuff);
Victor Stinner0327bde2017-11-23 17:03:20 +0100255 if (n + k > MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000256 k = MAXPATHLEN - n;
Victor Stinner0327bde2017-11-23 17:03:20 +0100257 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000258 wcsncpy(buffer+n, stuff, k);
Fred Drakeedabdc12000-07-08 06:16:37 +0000259 buffer[n+k] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000260}
261
Victor Stinner0327bde2017-11-23 17:03:20 +0100262
Guido van Rossume296ced2001-09-28 20:00:29 +0000263/* copy_absolute requires that path be allocated at least
264 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000265static void
Victor Stinnerf4061da2010-10-14 12:37:19 +0000266copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000267{
Victor Stinner0327bde2017-11-23 17:03:20 +0100268 if (p[0] == SEP) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000269 wcscpy(path, p);
Victor Stinner0327bde2017-11-23 17:03:20 +0100270 }
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000271 else {
Victor Stinnerf4061da2010-10-14 12:37:19 +0000272 if (!_Py_wgetcwd(path, pathlen)) {
Victor Stinner4f3abb02010-10-07 23:29:18 +0000273 /* unable to get the current directory */
274 wcscpy(path, p);
275 return;
276 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100277 if (p[0] == '.' && p[1] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000278 p += 2;
Victor Stinner0327bde2017-11-23 17:03:20 +0100279 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000280 joinpath(path, p);
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000281 }
282}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000283
Victor Stinner0327bde2017-11-23 17:03:20 +0100284
Guido van Rossume296ced2001-09-28 20:00:29 +0000285/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
286static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000287absolutize(wchar_t *path)
Guido van Rossume296ced2001-09-28 20:00:29 +0000288{
Victor Stinnerf4061da2010-10-14 12:37:19 +0000289 wchar_t buffer[MAXPATHLEN+1];
Guido van Rossume296ced2001-09-28 20:00:29 +0000290
Victor Stinner0327bde2017-11-23 17:03:20 +0100291 if (path[0] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000292 return;
Victor Stinner0327bde2017-11-23 17:03:20 +0100293 }
Victor Stinnerf4061da2010-10-14 12:37:19 +0000294 copy_absolute(buffer, path, MAXPATHLEN+1);
Martin v. Löwis790465f2008-04-05 20:41:37 +0000295 wcscpy(path, buffer);
Guido van Rossume296ced2001-09-28 20:00:29 +0000296}
297
Victor Stinner0327bde2017-11-23 17:03:20 +0100298
Guido van Rossume296ced2001-09-28 20:00:29 +0000299/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000300 bytes long.
301*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000302static int
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100303search_for_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100304 PyCalculatePath *calculate, wchar_t *prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000305{
Fred Drakeedabdc12000-07-08 06:16:37 +0000306 size_t n;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000307 wchar_t *vpath;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000308
Fred Drakeedabdc12000-07-08 06:16:37 +0000309 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100310 if (core_config->home) {
311 wcsncpy(prefix, core_config->home, MAXPATHLEN);
Victor Stinner9316ee42017-11-25 03:17:57 +0100312 prefix[MAXPATHLEN] = L'\0';
313 wchar_t *delim = wcschr(prefix, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100314 if (delim) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000315 *delim = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100316 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100317 joinpath(prefix, calculate->lib_python);
318 joinpath(prefix, LANDMARK);
Fred Drakeedabdc12000-07-08 06:16:37 +0000319 return 1;
320 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000321
Fred Drakeedabdc12000-07-08 06:16:37 +0000322 /* Check to see if argv[0] is in the build directory */
Victor Stinner9316ee42017-11-25 03:17:57 +0100323 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
324 prefix[MAXPATHLEN] = L'\0';
Antoine Pitrou961d54c2018-07-16 19:03:03 +0200325 joinpath(prefix, L"Modules/Setup.local");
Victor Stinner9316ee42017-11-25 03:17:57 +0100326 if (isfile(prefix)) {
Neil Schemenauer6cf07022001-01-24 17:13:11 +0000327 /* Check VPATH to see if argv0_path is in the build directory. */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200328 vpath = Py_DecodeLocale(VPATH, NULL);
Victor Stinner21582312010-10-23 00:13:28 +0000329 if (vpath != NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100330 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
331 prefix[MAXPATHLEN] = L'\0';
332 joinpath(prefix, vpath);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200333 PyMem_RawFree(vpath);
Victor Stinner9316ee42017-11-25 03:17:57 +0100334 joinpath(prefix, L"Lib");
335 joinpath(prefix, LANDMARK);
336 if (ismodule(prefix)) {
Victor Stinner21582312010-10-23 00:13:28 +0000337 return -1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100338 }
Victor Stinner21582312010-10-23 00:13:28 +0000339 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000340 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000341
Fred Drakeedabdc12000-07-08 06:16:37 +0000342 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100343 copy_absolute(prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000344 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100345 n = wcslen(prefix);
346 joinpath(prefix, calculate->lib_python);
347 joinpath(prefix, LANDMARK);
348 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000349 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100350 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100351 prefix[n] = L'\0';
352 reduce(prefix);
353 } while (prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000354
Fred Drakeedabdc12000-07-08 06:16:37 +0000355 /* Look at configure's PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100356 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
357 prefix[MAXPATHLEN] = L'\0';
358 joinpath(prefix, calculate->lib_python);
359 joinpath(prefix, LANDMARK);
360 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000361 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100362 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000363
Fred Drakeedabdc12000-07-08 06:16:37 +0000364 /* Fail */
365 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000366}
367
368
Victor Stinner0327bde2017-11-23 17:03:20 +0100369static void
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100370calculate_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100371 PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100372{
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100373 calculate->prefix_found = search_for_prefix(core_config, calculate, prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100374 if (!calculate->prefix_found) {
Victor Stinnerb75d7e22018-08-01 02:13:04 +0200375 if (!core_config->_frozen) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100376 fprintf(stderr,
377 "Could not find platform independent libraries <prefix>\n");
378 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100379 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
380 joinpath(prefix, calculate->lib_python);
Victor Stinner0327bde2017-11-23 17:03:20 +0100381 }
382 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100383 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100384 }
385}
386
387
388static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100389calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100390{
391 /* Reduce prefix and exec_prefix to their essence,
392 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
393 * If we're loading relative to the build directory,
394 * return the compiled-in defaults instead.
395 */
396 if (calculate->prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100397 reduce(prefix);
398 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100399 /* The prefix is the root directory, but reduce() chopped
400 * off the "/". */
Victor Stinner9316ee42017-11-25 03:17:57 +0100401 if (!prefix[0]) {
402 wcscpy(prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100403 }
404 }
405 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100406 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100407 }
408}
409
410
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000411/* search_for_exec_prefix requires that argv0_path be no more than
Guido van Rossume296ced2001-09-28 20:00:29 +0000412 MAXPATHLEN bytes long.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000413*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000414static int
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100415search_for_exec_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100416 PyCalculatePath *calculate, wchar_t *exec_prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000417{
Fred Drakeedabdc12000-07-08 06:16:37 +0000418 size_t n;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000419
Fred Drakeedabdc12000-07-08 06:16:37 +0000420 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100421 if (core_config->home) {
422 wchar_t *delim = wcschr(core_config->home, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100423 if (delim) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100424 wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100425 }
426 else {
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100427 wcsncpy(exec_prefix, core_config->home, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100428 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100429 exec_prefix[MAXPATHLEN] = L'\0';
430 joinpath(exec_prefix, calculate->lib_python);
431 joinpath(exec_prefix, L"lib-dynload");
Fred Drakeedabdc12000-07-08 06:16:37 +0000432 return 1;
433 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000434
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000435 /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
436 is written by setup.py and contains the relative path to the location
437 of shared library modules. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100438 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
439 exec_prefix[MAXPATHLEN] = L'\0';
440 joinpath(exec_prefix, L"pybuilddir.txt");
441 if (isfile(exec_prefix)) {
442 FILE *f = _Py_wfopen(exec_prefix, L"rb");
Victor Stinner0327bde2017-11-23 17:03:20 +0100443 if (f == NULL) {
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000444 errno = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100445 }
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000446 else {
447 char buf[MAXPATHLEN+1];
Victor Stinner9bee3292017-12-21 16:49:13 +0100448 wchar_t *rel_builddir_path;
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000449 n = fread(buf, 1, MAXPATHLEN, f);
450 buf[n] = '\0';
451 fclose(f);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100452 rel_builddir_path = _Py_DecodeUTF8_surrogateescape(buf, n);
453 if (rel_builddir_path) {
Victor Stinner9bee3292017-12-21 16:49:13 +0100454 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
455 exec_prefix[MAXPATHLEN] = L'\0';
456 joinpath(exec_prefix, rel_builddir_path);
457 PyMem_RawFree(rel_builddir_path );
458 return -1;
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000459 }
460 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000461 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000462
Fred Drakeedabdc12000-07-08 06:16:37 +0000463 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100464 copy_absolute(exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000465 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100466 n = wcslen(exec_prefix);
467 joinpath(exec_prefix, calculate->lib_python);
468 joinpath(exec_prefix, L"lib-dynload");
469 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000470 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100471 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100472 exec_prefix[n] = L'\0';
473 reduce(exec_prefix);
474 } while (exec_prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000475
Fred Drakeedabdc12000-07-08 06:16:37 +0000476 /* Look at configure's EXEC_PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100477 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
478 exec_prefix[MAXPATHLEN] = L'\0';
479 joinpath(exec_prefix, calculate->lib_python);
480 joinpath(exec_prefix, L"lib-dynload");
481 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000482 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100483 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000484
Fred Drakeedabdc12000-07-08 06:16:37 +0000485 /* Fail */
486 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000487}
488
Guido van Rossum305e5d01997-04-11 17:18:45 +0000489
Victor Stinner0327bde2017-11-23 17:03:20 +0100490static void
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100491calculate_exec_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100492 PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100493{
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100494 calculate->exec_prefix_found = search_for_exec_prefix(core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100495 calculate,
496 exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100497 if (!calculate->exec_prefix_found) {
Victor Stinnerb75d7e22018-08-01 02:13:04 +0200498 if (!core_config->_frozen) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100499 fprintf(stderr,
500 "Could not find platform dependent libraries <exec_prefix>\n");
501 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100502 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
503 joinpath(exec_prefix, L"lib/lib-dynload");
Victor Stinner0327bde2017-11-23 17:03:20 +0100504 }
505 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
506}
507
508
509static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100510calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100511{
512 if (calculate->exec_prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100513 reduce(exec_prefix);
514 reduce(exec_prefix);
515 reduce(exec_prefix);
516 if (!exec_prefix[0]) {
517 wcscpy(exec_prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100518 }
519 }
520 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100521 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100522 }
523}
524
525
Victor Stinner9316ee42017-11-25 03:17:57 +0100526static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100527calculate_program_full_path(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100528 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100529{
Victor Stinnerb64de462017-12-01 18:27:09 +0100530 wchar_t program_full_path[MAXPATHLEN+1];
531 memset(program_full_path, 0, sizeof(program_full_path));
Victor Stinner9316ee42017-11-25 03:17:57 +0100532
Victor Stinnerb9197952017-11-23 19:02:04 +0100533#ifdef __APPLE__
534#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
535 uint32_t nsexeclength = MAXPATHLEN;
536#else
537 unsigned long nsexeclength = MAXPATHLEN;
538#endif
539 char execpath[MAXPATHLEN+1];
540#endif
541
Victor Stinner0327bde2017-11-23 17:03:20 +0100542 /* If there is no slash in the argv0 path, then we have to
543 * assume python is on the user's $PATH, since there's no
544 * other way to find a directory to start the search from. If
545 * $PATH isn't exported, you lose.
546 */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100547 if (wcschr(core_config->program_name, SEP)) {
548 wcsncpy(program_full_path, core_config->program_name, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100549 }
Jack Jansen1afd4802004-06-03 14:33:03 +0000550#ifdef __APPLE__
Jack Jansen1afd4802004-06-03 14:33:03 +0000551 /* On Mac OS X, if a script uses an interpreter of the form
552 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
553 * as argv[0], which falls through to the $PATH search below.
554 * If /opt/python2.3/bin isn't in your path, or is near the end,
555 * this algorithm may incorrectly find /usr/bin/python. To work
556 * around this, we can use _NSGetExecutablePath to get a better
557 * hint of what the intended interpreter was, although this
558 * will fail if a relative path was used. but in that case,
559 * absolutize() should help us out below
560 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100561 else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
562 execpath[0] == SEP)
563 {
Victor Stinner31a83932017-12-04 13:39:15 +0100564 size_t len;
565 wchar_t *path = Py_DecodeLocale(execpath, &len);
566 if (path == NULL) {
567 return DECODE_LOCALE_ERR("executable path", len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 }
Victor Stinner31a83932017-12-04 13:39:15 +0100569 wcsncpy(program_full_path, path, MAXPATHLEN);
570 PyMem_RawFree(path);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000571 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000572#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100573 else if (calculate->path_env) {
574 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000575 while (1) {
576 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000577
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000578 if (delim) {
579 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100580 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000581 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100582 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100583 wcsncpy(program_full_path, path, len);
584 program_full_path[len] = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000585 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100586 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100587 wcsncpy(program_full_path, path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100588 }
Jack Jansen55070f52001-12-02 23:56:28 +0000589
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100590 joinpath(program_full_path, core_config->program_name);
Victor Stinnerb64de462017-12-01 18:27:09 +0100591 if (isxfile(program_full_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000592 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100593 }
Jack Jansen55070f52001-12-02 23:56:28 +0000594
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000595 if (!delim) {
Victor Stinnerb64de462017-12-01 18:27:09 +0100596 program_full_path[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000597 break;
598 }
599 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000601 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100602 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100603 program_full_path[0] = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100604 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100605 if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
606 absolutize(program_full_path);
Victor Stinner0327bde2017-11-23 17:03:20 +0100607 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100608
Victor Stinnerb64de462017-12-01 18:27:09 +0100609 config->program_full_path = _PyMem_RawWcsdup(program_full_path);
610 if (config->program_full_path == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100611 return _Py_INIT_NO_MEMORY();
612 }
613 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100614}
615
616
Victor Stinner9316ee42017-11-25 03:17:57 +0100617static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100618calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path)
Victor Stinner0327bde2017-11-23 17:03:20 +0100619{
Victor Stinnerb64de462017-12-01 18:27:09 +0100620 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100621 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000622
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000623#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100624 NSModule pythonModule;
625
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000626 /* On Mac OS X we have a special case if we're running from a framework.
627 ** This is because the python home should be set relative to the library,
628 ** which is in the framework, not relative to the executable, which may
629 ** be outside of the framework. Except when we're in the build directory...
630 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000631 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
632 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100633 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100634 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000635 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000636 /* See if we might be in the build directory. The framework in the
637 ** build directory is incomplete, it only has the .dylib and a few
638 ** needed symlinks, it doesn't have the Lib directories and such.
639 ** If we're running with the framework from the build directory we must
640 ** be running the interpreter in the build directory, so we use the
641 ** build-directory-specific logic to find Lib and such.
642 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100643 size_t len;
644 wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100645 if (wbuf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100646 return DECODE_LOCALE_ERR("framework location", len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100647 }
648
Victor Stinner0327bde2017-11-23 17:03:20 +0100649 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
650 reduce(calculate->argv0_path);
651 joinpath(calculate->argv0_path, calculate->lib_python);
652 joinpath(calculate->argv0_path, LANDMARK);
653 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000654 /* We are in the build directory so use the name of the
655 executable - we know that the absolute path is passed */
Victor Stinnerb64de462017-12-01 18:27:09 +0100656 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000657 }
658 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100659 /* Use the location of the library as the program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100660 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000661 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200662 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000663 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000664#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000665
Guido van Rossum305e5d01997-04-11 17:18:45 +0000666#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100667 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinnerb64de462017-12-01 18:27:09 +0100668 int linklen = _Py_wreadlink(program_full_path, tmpbuffer, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100669 while (linklen != -1) {
670 if (tmpbuffer[0] == SEP) {
671 /* tmpbuffer should never be longer than MAXPATHLEN,
672 but extra check does not hurt */
673 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000674 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100675 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100676 /* Interpret relative to program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100677 reduce(calculate->argv0_path);
678 joinpath(calculate->argv0_path, tmpbuffer);
679 }
680 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000681 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000682#endif /* HAVE_READLINK */
683
Victor Stinner0327bde2017-11-23 17:03:20 +0100684 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000685 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100686 MAXPATHLEN bytes long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100687 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100688}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000689
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100690
Victor Stinner0327bde2017-11-23 17:03:20 +0100691/* Search for an "pyvenv.cfg" environment configuration file, first in the
692 executable's directory and then in the parent directory.
693 If found, open it for use when searching for prefixes.
694*/
695static void
696calculate_read_pyenv(PyCalculatePath *calculate)
697{
698 wchar_t tmpbuffer[MAXPATHLEN+1];
699 wchar_t *env_cfg = L"pyvenv.cfg";
700 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100701
Victor Stinner0327bde2017-11-23 17:03:20 +0100702 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100703
Victor Stinner0327bde2017-11-23 17:03:20 +0100704 joinpath(tmpbuffer, env_cfg);
705 env_file = _Py_wfopen(tmpbuffer, L"r");
706 if (env_file == NULL) {
707 errno = 0;
708
709 reduce(tmpbuffer);
710 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100711 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100712
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100713 env_file = _Py_wfopen(tmpbuffer, L"r");
714 if (env_file == NULL) {
715 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100716 }
717 }
718
Victor Stinner0327bde2017-11-23 17:03:20 +0100719 if (env_file == NULL) {
720 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000721 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000722
Victor Stinner0327bde2017-11-23 17:03:20 +0100723 /* Look for a 'home' variable and set argv0_path to it, if found */
Victor Stinner9bee3292017-12-21 16:49:13 +0100724 if (_Py_FindEnvConfigValue(env_file, L"home", tmpbuffer, MAXPATHLEN)) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100725 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000726 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100727 fclose(env_file);
728}
Just van Rossum52e14d62002-12-30 22:08:05 +0000729
Guido van Rossum305e5d01997-04-11 17:18:45 +0000730
Victor Stinner0327bde2017-11-23 17:03:20 +0100731static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100732calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100733{
Victor Stinner9316ee42017-11-25 03:17:57 +0100734 wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100735 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000736
Victor Stinner0327bde2017-11-23 17:03:20 +0100737 if (calculate->prefix_found > 0) {
738 /* Use the reduced prefix returned by Py_GetPrefix() */
739 reduce(calculate->zip_path);
740 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100741 }
742 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100743 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
744 }
745 joinpath(calculate->zip_path, L"lib/python00.zip");
746
747 /* Replace "00" with version */
748 size_t bufsz = wcslen(calculate->zip_path);
749 calculate->zip_path[bufsz - 6] = VERSION[0];
750 calculate->zip_path[bufsz - 5] = VERSION[2];
751}
752
753
Victor Stinner9316ee42017-11-25 03:17:57 +0100754static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100755calculate_module_search_path(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100756 PyCalculatePath *calculate,
Victor Stinner9316ee42017-11-25 03:17:57 +0100757 const wchar_t *prefix, const wchar_t *exec_prefix,
Victor Stinnerb64de462017-12-01 18:27:09 +0100758 _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100759{
760 /* Calculate size of return buffer */
761 size_t bufsz = 0;
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100762 if (core_config->module_search_path_env != NULL) {
763 bufsz += wcslen(core_config->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000764 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000765
Victor Stinner0327bde2017-11-23 17:03:20 +0100766 wchar_t *defpath = calculate->pythonpath;
Victor Stinner9316ee42017-11-25 03:17:57 +0100767 size_t prefixsz = wcslen(prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000768 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000769 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000770
Victor Stinner0327bde2017-11-23 17:03:20 +0100771 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000772 /* Paths are relative to prefix */
773 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100774 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000775
Victor Stinner0327bde2017-11-23 17:03:20 +0100776 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000777 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100778 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000779 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000780 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000781 break;
782 }
783 defpath = delim + 1;
784 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000785
Victor Stinner0327bde2017-11-23 17:03:20 +0100786 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner9316ee42017-11-25 03:17:57 +0100787 bufsz += wcslen(exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000788
Victor Stinner0327bde2017-11-23 17:03:20 +0100789 /* Allocate the buffer */
790 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000791 if (buf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100792 return _Py_INIT_NO_MEMORY();
Fred Drakeedabdc12000-07-08 06:16:37 +0000793 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100794 buf[0] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000795
Victor Stinner72967a42013-11-16 01:22:04 +0100796 /* Run-time value of $PYTHONPATH goes first */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100797 if (core_config->module_search_path_env) {
798 wcscpy(buf, core_config->module_search_path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100799 wcscat(buf, delimiter);
Fred Drakeedabdc12000-07-08 06:16:37 +0000800 }
Victor Stinner72967a42013-11-16 01:22:04 +0100801
802 /* Next is the default zip path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100803 wcscat(buf, calculate->zip_path);
Victor Stinner72967a42013-11-16 01:22:04 +0100804 wcscat(buf, delimiter);
805
806 /* Next goes merge of compile-time $PYTHONPATH with
807 * dynamically located prefix.
808 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100809 defpath = calculate->pythonpath;
Victor Stinner72967a42013-11-16 01:22:04 +0100810 while (1) {
811 wchar_t *delim = wcschr(defpath, DELIM);
812
813 if (defpath[0] != SEP) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100814 wcscat(buf, prefix);
815 if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
Victor Stinner0327bde2017-11-23 17:03:20 +0100816 defpath[0] != (delim ? DELIM : L'\0'))
817 {
818 /* not empty */
Serhiy Storchaka62e32d62016-11-11 12:05:01 +0200819 wcscat(buf, separator);
820 }
Victor Stinner72967a42013-11-16 01:22:04 +0100821 }
822
823 if (delim) {
824 size_t len = delim - defpath + 1;
825 size_t end = wcslen(buf) + len;
826 wcsncat(buf, defpath, len);
Victor Stinner9316ee42017-11-25 03:17:57 +0100827 buf[end] = '\0';
Victor Stinner72967a42013-11-16 01:22:04 +0100828 }
829 else {
830 wcscat(buf, defpath);
831 break;
832 }
833 defpath = delim + 1;
834 }
835 wcscat(buf, delimiter);
836
837 /* Finally, on goes the directory for dynamic-load modules */
Victor Stinner9316ee42017-11-25 03:17:57 +0100838 wcscat(buf, exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100839
Victor Stinner9316ee42017-11-25 03:17:57 +0100840 config->module_search_path = buf;
841 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100842}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000843
Victor Stinner0327bde2017-11-23 17:03:20 +0100844
Victor Stinner0327bde2017-11-23 17:03:20 +0100845static _PyInitError
846calculate_init(PyCalculatePath *calculate,
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100847 const _PyCoreConfig *core_config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100848{
Victor Stinner0327bde2017-11-23 17:03:20 +0100849 size_t len;
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200850 const char *path = getenv("PATH");
Victor Stinner0327bde2017-11-23 17:03:20 +0100851 if (path) {
852 calculate->path_env = Py_DecodeLocale(path, &len);
853 if (!calculate->path_env) {
Victor Stinner46972b72017-11-24 22:55:40 +0100854 return DECODE_LOCALE_ERR("PATH environment variable", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100855 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000856 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000857
Victor Stinner0327bde2017-11-23 17:03:20 +0100858 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
859 if (!calculate->pythonpath) {
Victor Stinner46972b72017-11-24 22:55:40 +0100860 return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100861 }
862 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
863 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100864 return DECODE_LOCALE_ERR("PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100865 }
866 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
867 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100868 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100869 }
870 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
871 if (!calculate->lib_python) {
Victor Stinner46972b72017-11-24 22:55:40 +0100872 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100873 }
874 return _Py_INIT_OK();
875}
876
877
878static void
879calculate_free(PyCalculatePath *calculate)
880{
881 PyMem_RawFree(calculate->pythonpath);
882 PyMem_RawFree(calculate->prefix);
883 PyMem_RawFree(calculate->exec_prefix);
884 PyMem_RawFree(calculate->lib_python);
885 PyMem_RawFree(calculate->path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100886}
887
888
Victor Stinner9316ee42017-11-25 03:17:57 +0100889static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100890calculate_path_impl(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100891 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100892{
Victor Stinner31a83932017-12-04 13:39:15 +0100893 _PyInitError err;
894
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100895 err = calculate_program_full_path(core_config, calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100896 if (_Py_INIT_FAILED(err)) {
897 return err;
898 }
899
Victor Stinnerb64de462017-12-01 18:27:09 +0100900 err = calculate_argv0_path(calculate, config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100901 if (_Py_INIT_FAILED(err)) {
902 return err;
903 }
904
Victor Stinner0327bde2017-11-23 17:03:20 +0100905 calculate_read_pyenv(calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100906
907 wchar_t prefix[MAXPATHLEN+1];
908 memset(prefix, 0, sizeof(prefix));
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100909 calculate_prefix(core_config, calculate, prefix);
Victor Stinner9316ee42017-11-25 03:17:57 +0100910
911 calculate_zip_path(calculate, prefix);
912
913 wchar_t exec_prefix[MAXPATHLEN+1];
914 memset(exec_prefix, 0, sizeof(exec_prefix));
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100915 calculate_exec_prefix(core_config, calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100916
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100917 if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
Victor Stinnerb75d7e22018-08-01 02:13:04 +0200918 !core_config->_frozen)
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100919 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100920 fprintf(stderr,
921 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
922 }
923
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100924 err = calculate_module_search_path(core_config, calculate,
Victor Stinner31a83932017-12-04 13:39:15 +0100925 prefix, exec_prefix, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100926 if (_Py_INIT_FAILED(err)) {
927 return err;
928 }
929
930 calculate_reduce_prefix(calculate, prefix);
931
932 config->prefix = _PyMem_RawWcsdup(prefix);
933 if (config->prefix == NULL) {
934 return _Py_INIT_NO_MEMORY();
935 }
936
937 calculate_reduce_exec_prefix(calculate, exec_prefix);
938
939 config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
940 if (config->exec_prefix == NULL) {
941 return _Py_INIT_NO_MEMORY();
942 }
943
944 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100945}
946
947
Serhiy Storchaka13badcb2017-12-02 21:36:00 +0200948_PyInitError
Victor Stinnerb1147e42018-07-21 02:06:16 +0200949_PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config)
Serhiy Storchaka13badcb2017-12-02 21:36:00 +0200950{
Victor Stinner0327bde2017-11-23 17:03:20 +0100951 PyCalculatePath calculate;
952 memset(&calculate, 0, sizeof(calculate));
953
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100954 _PyInitError err = calculate_init(&calculate, core_config);
Victor Stinner0327bde2017-11-23 17:03:20 +0100955 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100956 goto done;
Victor Stinner0327bde2017-11-23 17:03:20 +0100957 }
958
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100959 err = calculate_path_impl(core_config, &calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100960 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100961 goto done;
962 }
963
Victor Stinner9316ee42017-11-25 03:17:57 +0100964 err = _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100965
Victor Stinner9316ee42017-11-25 03:17:57 +0100966done:
Victor Stinner0327bde2017-11-23 17:03:20 +0100967 calculate_free(&calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100968 return err;
969}
Victor Stinner46972b72017-11-24 22:55:40 +0100970
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000971#ifdef __cplusplus
972}
973#endif