blob: 521bc6e35ed3ee99ddaed043889ab7b3af46ab2f [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
E. M. Bray7a7693e2018-10-05 13:38:50 +0200299#if defined(__CYGWIN__) || defined(__MINGW32__)
300/* add_exe_suffix requires that progpath be allocated at least
301 MAXPATHLEN + 1 bytes.
302*/
303
304#ifndef EXE_SUFFIX
305#define EXE_SUFFIX L".exe"
306#endif
307
308static void
309add_exe_suffix(wchar_t *progpath)
310{
311 /* Check for already have an executable suffix */
312 size_t n = wcslen(progpath);
313 size_t s = wcslen(EXE_SUFFIX);
314 if (wcsncasecmp(EXE_SUFFIX, progpath+n-s, s) != 0) {
315 if (n + s > MAXPATHLEN) {
316 Py_FatalError("progpath overflow in getpath.c's add_exe_suffix()");
317 }
318 /* Save original path for revert */
319 wchar_t orig[MAXPATHLEN+1];
320 wcsncpy(orig, progpath, MAXPATHLEN);
321
322 wcsncpy(progpath+n, EXE_SUFFIX, s);
323 progpath[n+s] = '\0';
324
325 if (!isxfile(progpath)) {
326 /* Path that added suffix is invalid */
327 wcsncpy(progpath, orig, MAXPATHLEN);
328 }
329 }
330}
331#endif
332
333
Guido van Rossume296ced2001-09-28 20:00:29 +0000334/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000335 bytes long.
336*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000337static int
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100338search_for_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100339 PyCalculatePath *calculate, wchar_t *prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000340{
Fred Drakeedabdc12000-07-08 06:16:37 +0000341 size_t n;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000342 wchar_t *vpath;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000343
Fred Drakeedabdc12000-07-08 06:16:37 +0000344 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100345 if (core_config->home) {
346 wcsncpy(prefix, core_config->home, MAXPATHLEN);
Victor Stinner9316ee42017-11-25 03:17:57 +0100347 prefix[MAXPATHLEN] = L'\0';
348 wchar_t *delim = wcschr(prefix, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100349 if (delim) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000350 *delim = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100351 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100352 joinpath(prefix, calculate->lib_python);
353 joinpath(prefix, LANDMARK);
Fred Drakeedabdc12000-07-08 06:16:37 +0000354 return 1;
355 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000356
Fred Drakeedabdc12000-07-08 06:16:37 +0000357 /* Check to see if argv[0] is in the build directory */
Victor Stinner9316ee42017-11-25 03:17:57 +0100358 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
359 prefix[MAXPATHLEN] = L'\0';
Antoine Pitrou961d54c2018-07-16 19:03:03 +0200360 joinpath(prefix, L"Modules/Setup.local");
Victor Stinner9316ee42017-11-25 03:17:57 +0100361 if (isfile(prefix)) {
Neil Schemenauer6cf07022001-01-24 17:13:11 +0000362 /* Check VPATH to see if argv0_path is in the build directory. */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200363 vpath = Py_DecodeLocale(VPATH, NULL);
Victor Stinner21582312010-10-23 00:13:28 +0000364 if (vpath != NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100365 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
366 prefix[MAXPATHLEN] = L'\0';
367 joinpath(prefix, vpath);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200368 PyMem_RawFree(vpath);
Victor Stinner9316ee42017-11-25 03:17:57 +0100369 joinpath(prefix, L"Lib");
370 joinpath(prefix, LANDMARK);
371 if (ismodule(prefix)) {
Victor Stinner21582312010-10-23 00:13:28 +0000372 return -1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100373 }
Victor Stinner21582312010-10-23 00:13:28 +0000374 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000375 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000376
Fred Drakeedabdc12000-07-08 06:16:37 +0000377 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100378 copy_absolute(prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000379 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100380 n = wcslen(prefix);
381 joinpath(prefix, calculate->lib_python);
382 joinpath(prefix, LANDMARK);
383 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000384 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100385 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100386 prefix[n] = L'\0';
387 reduce(prefix);
388 } while (prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000389
Fred Drakeedabdc12000-07-08 06:16:37 +0000390 /* Look at configure's PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100391 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
392 prefix[MAXPATHLEN] = L'\0';
393 joinpath(prefix, calculate->lib_python);
394 joinpath(prefix, LANDMARK);
395 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000396 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100397 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000398
Fred Drakeedabdc12000-07-08 06:16:37 +0000399 /* Fail */
400 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000401}
402
403
Victor Stinner0327bde2017-11-23 17:03:20 +0100404static void
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100405calculate_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100406 PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100407{
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100408 calculate->prefix_found = search_for_prefix(core_config, calculate, prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100409 if (!calculate->prefix_found) {
Victor Stinnerb75d7e22018-08-01 02:13:04 +0200410 if (!core_config->_frozen) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100411 fprintf(stderr,
412 "Could not find platform independent libraries <prefix>\n");
413 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100414 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
415 joinpath(prefix, calculate->lib_python);
Victor Stinner0327bde2017-11-23 17:03:20 +0100416 }
417 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100418 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100419 }
420}
421
422
423static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100424calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100425{
426 /* Reduce prefix and exec_prefix to their essence,
427 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
428 * If we're loading relative to the build directory,
429 * return the compiled-in defaults instead.
430 */
431 if (calculate->prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100432 reduce(prefix);
433 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100434 /* The prefix is the root directory, but reduce() chopped
435 * off the "/". */
Victor Stinner9316ee42017-11-25 03:17:57 +0100436 if (!prefix[0]) {
437 wcscpy(prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100438 }
439 }
440 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100441 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100442 }
443}
444
445
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000446/* search_for_exec_prefix requires that argv0_path be no more than
Guido van Rossume296ced2001-09-28 20:00:29 +0000447 MAXPATHLEN bytes long.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000448*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000449static int
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100450search_for_exec_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100451 PyCalculatePath *calculate, wchar_t *exec_prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000452{
Fred Drakeedabdc12000-07-08 06:16:37 +0000453 size_t n;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000454
Fred Drakeedabdc12000-07-08 06:16:37 +0000455 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100456 if (core_config->home) {
457 wchar_t *delim = wcschr(core_config->home, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100458 if (delim) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100459 wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100460 }
461 else {
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100462 wcsncpy(exec_prefix, core_config->home, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100463 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100464 exec_prefix[MAXPATHLEN] = L'\0';
465 joinpath(exec_prefix, calculate->lib_python);
466 joinpath(exec_prefix, L"lib-dynload");
Fred Drakeedabdc12000-07-08 06:16:37 +0000467 return 1;
468 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000469
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000470 /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
471 is written by setup.py and contains the relative path to the location
472 of shared library modules. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100473 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
474 exec_prefix[MAXPATHLEN] = L'\0';
475 joinpath(exec_prefix, L"pybuilddir.txt");
476 if (isfile(exec_prefix)) {
477 FILE *f = _Py_wfopen(exec_prefix, L"rb");
Victor Stinner0327bde2017-11-23 17:03:20 +0100478 if (f == NULL) {
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000479 errno = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100480 }
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000481 else {
482 char buf[MAXPATHLEN+1];
Victor Stinner9bee3292017-12-21 16:49:13 +0100483 wchar_t *rel_builddir_path;
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000484 n = fread(buf, 1, MAXPATHLEN, f);
485 buf[n] = '\0';
486 fclose(f);
Victor Stinner7ed7aea2018-01-15 10:45:49 +0100487 rel_builddir_path = _Py_DecodeUTF8_surrogateescape(buf, n);
488 if (rel_builddir_path) {
Victor Stinner9bee3292017-12-21 16:49:13 +0100489 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
490 exec_prefix[MAXPATHLEN] = L'\0';
491 joinpath(exec_prefix, rel_builddir_path);
492 PyMem_RawFree(rel_builddir_path );
493 return -1;
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000494 }
495 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000496 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000497
Fred Drakeedabdc12000-07-08 06:16:37 +0000498 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100499 copy_absolute(exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000500 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100501 n = wcslen(exec_prefix);
502 joinpath(exec_prefix, calculate->lib_python);
503 joinpath(exec_prefix, L"lib-dynload");
504 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000505 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100506 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100507 exec_prefix[n] = L'\0';
508 reduce(exec_prefix);
509 } while (exec_prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000510
Fred Drakeedabdc12000-07-08 06:16:37 +0000511 /* Look at configure's EXEC_PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100512 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
513 exec_prefix[MAXPATHLEN] = L'\0';
514 joinpath(exec_prefix, calculate->lib_python);
515 joinpath(exec_prefix, L"lib-dynload");
516 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000517 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100518 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000519
Fred Drakeedabdc12000-07-08 06:16:37 +0000520 /* Fail */
521 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000522}
523
Guido van Rossum305e5d01997-04-11 17:18:45 +0000524
Victor Stinner0327bde2017-11-23 17:03:20 +0100525static void
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100526calculate_exec_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100527 PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100528{
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100529 calculate->exec_prefix_found = search_for_exec_prefix(core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100530 calculate,
531 exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100532 if (!calculate->exec_prefix_found) {
Victor Stinnerb75d7e22018-08-01 02:13:04 +0200533 if (!core_config->_frozen) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100534 fprintf(stderr,
535 "Could not find platform dependent libraries <exec_prefix>\n");
536 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100537 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
538 joinpath(exec_prefix, L"lib/lib-dynload");
Victor Stinner0327bde2017-11-23 17:03:20 +0100539 }
540 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
541}
542
543
544static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100545calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100546{
547 if (calculate->exec_prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100548 reduce(exec_prefix);
549 reduce(exec_prefix);
550 reduce(exec_prefix);
551 if (!exec_prefix[0]) {
552 wcscpy(exec_prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100553 }
554 }
555 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100556 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100557 }
558}
559
560
Victor Stinner9316ee42017-11-25 03:17:57 +0100561static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100562calculate_program_full_path(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100563 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100564{
Victor Stinnerb64de462017-12-01 18:27:09 +0100565 wchar_t program_full_path[MAXPATHLEN+1];
566 memset(program_full_path, 0, sizeof(program_full_path));
Victor Stinner9316ee42017-11-25 03:17:57 +0100567
Victor Stinnerb9197952017-11-23 19:02:04 +0100568#ifdef __APPLE__
569#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
570 uint32_t nsexeclength = MAXPATHLEN;
571#else
572 unsigned long nsexeclength = MAXPATHLEN;
573#endif
574 char execpath[MAXPATHLEN+1];
575#endif
576
Victor Stinner0327bde2017-11-23 17:03:20 +0100577 /* If there is no slash in the argv0 path, then we have to
578 * assume python is on the user's $PATH, since there's no
579 * other way to find a directory to start the search from. If
580 * $PATH isn't exported, you lose.
581 */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100582 if (wcschr(core_config->program_name, SEP)) {
583 wcsncpy(program_full_path, core_config->program_name, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100584 }
Jack Jansen1afd4802004-06-03 14:33:03 +0000585#ifdef __APPLE__
Jack Jansen1afd4802004-06-03 14:33:03 +0000586 /* On Mac OS X, if a script uses an interpreter of the form
587 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
588 * as argv[0], which falls through to the $PATH search below.
589 * If /opt/python2.3/bin isn't in your path, or is near the end,
590 * this algorithm may incorrectly find /usr/bin/python. To work
591 * around this, we can use _NSGetExecutablePath to get a better
592 * hint of what the intended interpreter was, although this
593 * will fail if a relative path was used. but in that case,
594 * absolutize() should help us out below
595 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100596 else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
597 execpath[0] == SEP)
598 {
Victor Stinner31a83932017-12-04 13:39:15 +0100599 size_t len;
600 wchar_t *path = Py_DecodeLocale(execpath, &len);
601 if (path == NULL) {
602 return DECODE_LOCALE_ERR("executable path", len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 }
Victor Stinner31a83932017-12-04 13:39:15 +0100604 wcsncpy(program_full_path, path, MAXPATHLEN);
605 PyMem_RawFree(path);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000606 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000607#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100608 else if (calculate->path_env) {
609 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000610 while (1) {
611 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000612
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000613 if (delim) {
614 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100615 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000616 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100617 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100618 wcsncpy(program_full_path, path, len);
619 program_full_path[len] = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000620 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100621 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100622 wcsncpy(program_full_path, path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100623 }
Jack Jansen55070f52001-12-02 23:56:28 +0000624
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100625 joinpath(program_full_path, core_config->program_name);
Victor Stinnerb64de462017-12-01 18:27:09 +0100626 if (isxfile(program_full_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000627 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100628 }
Jack Jansen55070f52001-12-02 23:56:28 +0000629
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000630 if (!delim) {
Victor Stinnerb64de462017-12-01 18:27:09 +0100631 program_full_path[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000632 break;
633 }
634 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000636 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100637 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100638 program_full_path[0] = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100639 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100640 if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
641 absolutize(program_full_path);
Victor Stinner0327bde2017-11-23 17:03:20 +0100642 }
E. M. Bray7a7693e2018-10-05 13:38:50 +0200643#if defined(__CYGWIN__) || defined(__MINGW32__)
644 /* For these platforms it is necessary to ensure that the .exe suffix
645 * is appended to the filename, otherwise there is potential for
646 * sys.executable to return the name of a directory under the same
647 * path (bpo-28441).
648 */
649 if (program_full_path[0] != '\0') {
650 add_exe_suffix(program_full_path);
651 }
652#endif
Victor Stinner9316ee42017-11-25 03:17:57 +0100653
Victor Stinnerb64de462017-12-01 18:27:09 +0100654 config->program_full_path = _PyMem_RawWcsdup(program_full_path);
655 if (config->program_full_path == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100656 return _Py_INIT_NO_MEMORY();
657 }
658 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100659}
660
661
Victor Stinner9316ee42017-11-25 03:17:57 +0100662static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100663calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path)
Victor Stinner0327bde2017-11-23 17:03:20 +0100664{
Victor Stinnerb64de462017-12-01 18:27:09 +0100665 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100666 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000667
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000668#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100669 NSModule pythonModule;
670
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000671 /* On Mac OS X we have a special case if we're running from a framework.
672 ** This is because the python home should be set relative to the library,
673 ** which is in the framework, not relative to the executable, which may
674 ** be outside of the framework. Except when we're in the build directory...
675 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000676 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
677 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100678 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100679 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000680 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000681 /* See if we might be in the build directory. The framework in the
682 ** build directory is incomplete, it only has the .dylib and a few
683 ** needed symlinks, it doesn't have the Lib directories and such.
684 ** If we're running with the framework from the build directory we must
685 ** be running the interpreter in the build directory, so we use the
686 ** build-directory-specific logic to find Lib and such.
687 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100688 size_t len;
689 wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100690 if (wbuf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100691 return DECODE_LOCALE_ERR("framework location", len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100692 }
693
Victor Stinner0327bde2017-11-23 17:03:20 +0100694 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
695 reduce(calculate->argv0_path);
696 joinpath(calculate->argv0_path, calculate->lib_python);
697 joinpath(calculate->argv0_path, LANDMARK);
698 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000699 /* We are in the build directory so use the name of the
700 executable - we know that the absolute path is passed */
Victor Stinnerb64de462017-12-01 18:27:09 +0100701 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000702 }
703 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100704 /* Use the location of the library as the program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100705 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000706 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200707 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000708 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000709#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000710
Guido van Rossum305e5d01997-04-11 17:18:45 +0000711#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100712 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinnerb64de462017-12-01 18:27:09 +0100713 int linklen = _Py_wreadlink(program_full_path, tmpbuffer, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100714 while (linklen != -1) {
715 if (tmpbuffer[0] == SEP) {
716 /* tmpbuffer should never be longer than MAXPATHLEN,
717 but extra check does not hurt */
718 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000719 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100720 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100721 /* Interpret relative to program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100722 reduce(calculate->argv0_path);
723 joinpath(calculate->argv0_path, tmpbuffer);
724 }
725 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000726 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000727#endif /* HAVE_READLINK */
728
Victor Stinner0327bde2017-11-23 17:03:20 +0100729 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000730 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100731 MAXPATHLEN bytes long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100732 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100733}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000734
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100735
Victor Stinner0327bde2017-11-23 17:03:20 +0100736/* Search for an "pyvenv.cfg" environment configuration file, first in the
737 executable's directory and then in the parent directory.
738 If found, open it for use when searching for prefixes.
739*/
740static void
741calculate_read_pyenv(PyCalculatePath *calculate)
742{
743 wchar_t tmpbuffer[MAXPATHLEN+1];
744 wchar_t *env_cfg = L"pyvenv.cfg";
745 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100746
Victor Stinner0327bde2017-11-23 17:03:20 +0100747 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100748
Victor Stinner0327bde2017-11-23 17:03:20 +0100749 joinpath(tmpbuffer, env_cfg);
750 env_file = _Py_wfopen(tmpbuffer, L"r");
751 if (env_file == NULL) {
752 errno = 0;
753
754 reduce(tmpbuffer);
755 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100756 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100757
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100758 env_file = _Py_wfopen(tmpbuffer, L"r");
759 if (env_file == NULL) {
760 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100761 }
762 }
763
Victor Stinner0327bde2017-11-23 17:03:20 +0100764 if (env_file == NULL) {
765 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000766 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000767
Victor Stinner0327bde2017-11-23 17:03:20 +0100768 /* Look for a 'home' variable and set argv0_path to it, if found */
Victor Stinner9bee3292017-12-21 16:49:13 +0100769 if (_Py_FindEnvConfigValue(env_file, L"home", tmpbuffer, MAXPATHLEN)) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100770 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000771 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100772 fclose(env_file);
773}
Just van Rossum52e14d62002-12-30 22:08:05 +0000774
Guido van Rossum305e5d01997-04-11 17:18:45 +0000775
Victor Stinner0327bde2017-11-23 17:03:20 +0100776static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100777calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100778{
Victor Stinner9316ee42017-11-25 03:17:57 +0100779 wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100780 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000781
Victor Stinner0327bde2017-11-23 17:03:20 +0100782 if (calculate->prefix_found > 0) {
783 /* Use the reduced prefix returned by Py_GetPrefix() */
784 reduce(calculate->zip_path);
785 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100786 }
787 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100788 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
789 }
790 joinpath(calculate->zip_path, L"lib/python00.zip");
791
792 /* Replace "00" with version */
793 size_t bufsz = wcslen(calculate->zip_path);
794 calculate->zip_path[bufsz - 6] = VERSION[0];
795 calculate->zip_path[bufsz - 5] = VERSION[2];
796}
797
798
Victor Stinner9316ee42017-11-25 03:17:57 +0100799static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100800calculate_module_search_path(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100801 PyCalculatePath *calculate,
Victor Stinner9316ee42017-11-25 03:17:57 +0100802 const wchar_t *prefix, const wchar_t *exec_prefix,
Victor Stinnerb64de462017-12-01 18:27:09 +0100803 _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100804{
805 /* Calculate size of return buffer */
806 size_t bufsz = 0;
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100807 if (core_config->module_search_path_env != NULL) {
808 bufsz += wcslen(core_config->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000809 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000810
Victor Stinner0327bde2017-11-23 17:03:20 +0100811 wchar_t *defpath = calculate->pythonpath;
Victor Stinner9316ee42017-11-25 03:17:57 +0100812 size_t prefixsz = wcslen(prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000813 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000814 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000815
Victor Stinner0327bde2017-11-23 17:03:20 +0100816 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000817 /* Paths are relative to prefix */
818 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100819 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000820
Victor Stinner0327bde2017-11-23 17:03:20 +0100821 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000822 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100823 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000824 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000825 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000826 break;
827 }
828 defpath = delim + 1;
829 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000830
Victor Stinner0327bde2017-11-23 17:03:20 +0100831 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner9316ee42017-11-25 03:17:57 +0100832 bufsz += wcslen(exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000833
Victor Stinner0327bde2017-11-23 17:03:20 +0100834 /* Allocate the buffer */
835 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000836 if (buf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100837 return _Py_INIT_NO_MEMORY();
Fred Drakeedabdc12000-07-08 06:16:37 +0000838 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100839 buf[0] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000840
Victor Stinner72967a42013-11-16 01:22:04 +0100841 /* Run-time value of $PYTHONPATH goes first */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100842 if (core_config->module_search_path_env) {
843 wcscpy(buf, core_config->module_search_path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100844 wcscat(buf, delimiter);
Fred Drakeedabdc12000-07-08 06:16:37 +0000845 }
Victor Stinner72967a42013-11-16 01:22:04 +0100846
847 /* Next is the default zip path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100848 wcscat(buf, calculate->zip_path);
Victor Stinner72967a42013-11-16 01:22:04 +0100849 wcscat(buf, delimiter);
850
851 /* Next goes merge of compile-time $PYTHONPATH with
852 * dynamically located prefix.
853 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100854 defpath = calculate->pythonpath;
Victor Stinner72967a42013-11-16 01:22:04 +0100855 while (1) {
856 wchar_t *delim = wcschr(defpath, DELIM);
857
858 if (defpath[0] != SEP) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100859 wcscat(buf, prefix);
860 if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
Victor Stinner0327bde2017-11-23 17:03:20 +0100861 defpath[0] != (delim ? DELIM : L'\0'))
862 {
863 /* not empty */
Serhiy Storchaka62e32d62016-11-11 12:05:01 +0200864 wcscat(buf, separator);
865 }
Victor Stinner72967a42013-11-16 01:22:04 +0100866 }
867
868 if (delim) {
869 size_t len = delim - defpath + 1;
870 size_t end = wcslen(buf) + len;
871 wcsncat(buf, defpath, len);
Victor Stinner9316ee42017-11-25 03:17:57 +0100872 buf[end] = '\0';
Victor Stinner72967a42013-11-16 01:22:04 +0100873 }
874 else {
875 wcscat(buf, defpath);
876 break;
877 }
878 defpath = delim + 1;
879 }
880 wcscat(buf, delimiter);
881
882 /* Finally, on goes the directory for dynamic-load modules */
Victor Stinner9316ee42017-11-25 03:17:57 +0100883 wcscat(buf, exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100884
Victor Stinner9316ee42017-11-25 03:17:57 +0100885 config->module_search_path = buf;
886 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100887}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000888
Victor Stinner0327bde2017-11-23 17:03:20 +0100889
Victor Stinner0327bde2017-11-23 17:03:20 +0100890static _PyInitError
891calculate_init(PyCalculatePath *calculate,
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100892 const _PyCoreConfig *core_config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100893{
Victor Stinner0327bde2017-11-23 17:03:20 +0100894 size_t len;
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200895 const char *path = getenv("PATH");
Victor Stinner0327bde2017-11-23 17:03:20 +0100896 if (path) {
897 calculate->path_env = Py_DecodeLocale(path, &len);
898 if (!calculate->path_env) {
Victor Stinner46972b72017-11-24 22:55:40 +0100899 return DECODE_LOCALE_ERR("PATH environment variable", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100900 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000901 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000902
Victor Stinner0327bde2017-11-23 17:03:20 +0100903 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
904 if (!calculate->pythonpath) {
Victor Stinner46972b72017-11-24 22:55:40 +0100905 return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100906 }
907 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
908 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100909 return DECODE_LOCALE_ERR("PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100910 }
911 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
912 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100913 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100914 }
915 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
916 if (!calculate->lib_python) {
Victor Stinner46972b72017-11-24 22:55:40 +0100917 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100918 }
919 return _Py_INIT_OK();
920}
921
922
923static void
924calculate_free(PyCalculatePath *calculate)
925{
926 PyMem_RawFree(calculate->pythonpath);
927 PyMem_RawFree(calculate->prefix);
928 PyMem_RawFree(calculate->exec_prefix);
929 PyMem_RawFree(calculate->lib_python);
930 PyMem_RawFree(calculate->path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100931}
932
933
Victor Stinner9316ee42017-11-25 03:17:57 +0100934static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100935calculate_path_impl(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100936 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100937{
Victor Stinner31a83932017-12-04 13:39:15 +0100938 _PyInitError err;
939
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100940 err = calculate_program_full_path(core_config, calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100941 if (_Py_INIT_FAILED(err)) {
942 return err;
943 }
944
Victor Stinnerb64de462017-12-01 18:27:09 +0100945 err = calculate_argv0_path(calculate, config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100946 if (_Py_INIT_FAILED(err)) {
947 return err;
948 }
949
Victor Stinner0327bde2017-11-23 17:03:20 +0100950 calculate_read_pyenv(calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100951
952 wchar_t prefix[MAXPATHLEN+1];
953 memset(prefix, 0, sizeof(prefix));
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100954 calculate_prefix(core_config, calculate, prefix);
Victor Stinner9316ee42017-11-25 03:17:57 +0100955
956 calculate_zip_path(calculate, prefix);
957
958 wchar_t exec_prefix[MAXPATHLEN+1];
959 memset(exec_prefix, 0, sizeof(exec_prefix));
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100960 calculate_exec_prefix(core_config, calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100961
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100962 if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
Victor Stinnerb75d7e22018-08-01 02:13:04 +0200963 !core_config->_frozen)
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100964 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100965 fprintf(stderr,
966 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
967 }
968
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100969 err = calculate_module_search_path(core_config, calculate,
Victor Stinner31a83932017-12-04 13:39:15 +0100970 prefix, exec_prefix, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100971 if (_Py_INIT_FAILED(err)) {
972 return err;
973 }
974
975 calculate_reduce_prefix(calculate, prefix);
976
977 config->prefix = _PyMem_RawWcsdup(prefix);
978 if (config->prefix == NULL) {
979 return _Py_INIT_NO_MEMORY();
980 }
981
982 calculate_reduce_exec_prefix(calculate, exec_prefix);
983
984 config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
985 if (config->exec_prefix == NULL) {
986 return _Py_INIT_NO_MEMORY();
987 }
988
989 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100990}
991
992
Serhiy Storchaka13badcb2017-12-02 21:36:00 +0200993_PyInitError
Victor Stinnerb1147e42018-07-21 02:06:16 +0200994_PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config)
Serhiy Storchaka13badcb2017-12-02 21:36:00 +0200995{
Victor Stinner0327bde2017-11-23 17:03:20 +0100996 PyCalculatePath calculate;
997 memset(&calculate, 0, sizeof(calculate));
998
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100999 _PyInitError err = calculate_init(&calculate, core_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001000 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001001 goto done;
Victor Stinner0327bde2017-11-23 17:03:20 +01001002 }
1003
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +01001004 err = calculate_path_impl(core_config, &calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +01001005 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001006 goto done;
1007 }
1008
Victor Stinner9316ee42017-11-25 03:17:57 +01001009 err = _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001010
Victor Stinner9316ee42017-11-25 03:17:57 +01001011done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001012 calculate_free(&calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +01001013 return err;
1014}
Victor Stinner46972b72017-11-24 22:55:40 +01001015
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001016#ifdef __cplusplus
1017}
1018#endif