blob: b4b33437b6f4be0c120a331a5636c8d3f25d7451 [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;
143 fname = Py_EncodeLocale(path, NULL);
144 if (fname == NULL) {
145 errno = EINVAL;
146 return -1;
147 }
148 err = stat(fname, buf);
149 PyMem_Free(fname);
150 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
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100299/* search for a prefix value in an environment file. If found, copy it
300 to the provided buffer, which is expected to be no more than MAXPATHLEN
301 bytes long.
302*/
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100303static int
304find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
305{
306 int result = 0; /* meaning not found */
307 char buffer[MAXPATHLEN*2+1]; /* allow extra for key, '=', etc. */
308
309 fseek(env_file, 0, SEEK_SET);
310 while (!feof(env_file)) {
311 char * p = fgets(buffer, MAXPATHLEN*2, env_file);
312 wchar_t tmpbuffer[MAXPATHLEN*2+1];
313 PyObject * decoded;
314 int n;
315
Victor Stinner0327bde2017-11-23 17:03:20 +0100316 if (p == NULL) {
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100317 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100318 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100319 n = strlen(p);
320 if (p[n - 1] != '\n') {
321 /* line has overflowed - bail */
322 break;
323 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100324 if (p[0] == '#') {
325 /* Comment - skip */
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100326 continue;
Victor Stinner0327bde2017-11-23 17:03:20 +0100327 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100328 decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
329 if (decoded != NULL) {
330 Py_ssize_t k;
331 wchar_t * state;
332 k = PyUnicode_AsWideChar(decoded,
333 tmpbuffer, MAXPATHLEN * 2);
334 Py_DECREF(decoded);
335 if (k >= 0) {
336 wchar_t * tok = wcstok(tmpbuffer, L" \t\r\n", &state);
337 if ((tok != NULL) && !wcscmp(tok, key)) {
338 tok = wcstok(NULL, L" \t", &state);
339 if ((tok != NULL) && !wcscmp(tok, L"=")) {
340 tok = wcstok(NULL, L"\r\n", &state);
341 if (tok != NULL) {
342 wcsncpy(value, tok, MAXPATHLEN);
343 result = 1;
344 break;
345 }
346 }
347 }
348 }
349 }
350 }
351 return result;
352}
353
Victor Stinner0327bde2017-11-23 17:03:20 +0100354
Guido van Rossume296ced2001-09-28 20:00:29 +0000355/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000356 bytes long.
357*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000358static int
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100359search_for_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100360 PyCalculatePath *calculate, wchar_t *prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000361{
Fred Drakeedabdc12000-07-08 06:16:37 +0000362 size_t n;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000363 wchar_t *vpath;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000364
Fred Drakeedabdc12000-07-08 06:16:37 +0000365 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100366 if (core_config->home) {
367 wcsncpy(prefix, core_config->home, MAXPATHLEN);
Victor Stinner9316ee42017-11-25 03:17:57 +0100368 prefix[MAXPATHLEN] = L'\0';
369 wchar_t *delim = wcschr(prefix, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100370 if (delim) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000371 *delim = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100372 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100373 joinpath(prefix, calculate->lib_python);
374 joinpath(prefix, LANDMARK);
Fred Drakeedabdc12000-07-08 06:16:37 +0000375 return 1;
376 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000377
Fred Drakeedabdc12000-07-08 06:16:37 +0000378 /* Check to see if argv[0] is in the build directory */
Victor Stinner9316ee42017-11-25 03:17:57 +0100379 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
380 prefix[MAXPATHLEN] = L'\0';
381 joinpath(prefix, L"Modules/Setup");
382 if (isfile(prefix)) {
Neil Schemenauer6cf07022001-01-24 17:13:11 +0000383 /* Check VPATH to see if argv0_path is in the build directory. */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200384 vpath = Py_DecodeLocale(VPATH, NULL);
Victor Stinner21582312010-10-23 00:13:28 +0000385 if (vpath != NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100386 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
387 prefix[MAXPATHLEN] = L'\0';
388 joinpath(prefix, vpath);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200389 PyMem_RawFree(vpath);
Victor Stinner9316ee42017-11-25 03:17:57 +0100390 joinpath(prefix, L"Lib");
391 joinpath(prefix, LANDMARK);
392 if (ismodule(prefix)) {
Victor Stinner21582312010-10-23 00:13:28 +0000393 return -1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100394 }
Victor Stinner21582312010-10-23 00:13:28 +0000395 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000396 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000397
Fred Drakeedabdc12000-07-08 06:16:37 +0000398 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100399 copy_absolute(prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000400 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100401 n = wcslen(prefix);
402 joinpath(prefix, calculate->lib_python);
403 joinpath(prefix, LANDMARK);
404 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000405 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100406 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100407 prefix[n] = L'\0';
408 reduce(prefix);
409 } while (prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000410
Fred Drakeedabdc12000-07-08 06:16:37 +0000411 /* Look at configure's PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100412 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
413 prefix[MAXPATHLEN] = L'\0';
414 joinpath(prefix, calculate->lib_python);
415 joinpath(prefix, LANDMARK);
416 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000417 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100418 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000419
Fred Drakeedabdc12000-07-08 06:16:37 +0000420 /* Fail */
421 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000422}
423
424
Victor Stinner0327bde2017-11-23 17:03:20 +0100425static void
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100426calculate_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100427 PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100428{
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100429 calculate->prefix_found = search_for_prefix(core_config, calculate, prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100430 if (!calculate->prefix_found) {
431 if (!Py_FrozenFlag) {
432 fprintf(stderr,
433 "Could not find platform independent libraries <prefix>\n");
434 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100435 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
436 joinpath(prefix, calculate->lib_python);
Victor Stinner0327bde2017-11-23 17:03:20 +0100437 }
438 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100439 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100440 }
441}
442
443
444static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100445calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100446{
447 /* Reduce prefix and exec_prefix to their essence,
448 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
449 * If we're loading relative to the build directory,
450 * return the compiled-in defaults instead.
451 */
452 if (calculate->prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100453 reduce(prefix);
454 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100455 /* The prefix is the root directory, but reduce() chopped
456 * off the "/". */
Victor Stinner9316ee42017-11-25 03:17:57 +0100457 if (!prefix[0]) {
458 wcscpy(prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100459 }
460 }
461 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100462 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100463 }
464}
465
466
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000467/* search_for_exec_prefix requires that argv0_path be no more than
Guido van Rossume296ced2001-09-28 20:00:29 +0000468 MAXPATHLEN bytes long.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000469*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000470static int
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100471search_for_exec_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100472 PyCalculatePath *calculate, wchar_t *exec_prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000473{
Fred Drakeedabdc12000-07-08 06:16:37 +0000474 size_t n;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000475
Fred Drakeedabdc12000-07-08 06:16:37 +0000476 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100477 if (core_config->home) {
478 wchar_t *delim = wcschr(core_config->home, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100479 if (delim) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100480 wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100481 }
482 else {
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100483 wcsncpy(exec_prefix, core_config->home, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100484 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100485 exec_prefix[MAXPATHLEN] = L'\0';
486 joinpath(exec_prefix, calculate->lib_python);
487 joinpath(exec_prefix, L"lib-dynload");
Fred Drakeedabdc12000-07-08 06:16:37 +0000488 return 1;
489 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000490
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000491 /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
492 is written by setup.py and contains the relative path to the location
493 of shared library modules. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100494 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
495 exec_prefix[MAXPATHLEN] = L'\0';
496 joinpath(exec_prefix, L"pybuilddir.txt");
497 if (isfile(exec_prefix)) {
498 FILE *f = _Py_wfopen(exec_prefix, L"rb");
Victor Stinner0327bde2017-11-23 17:03:20 +0100499 if (f == NULL) {
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000500 errno = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100501 }
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000502 else {
503 char buf[MAXPATHLEN+1];
504 PyObject *decoded;
505 wchar_t rel_builddir_path[MAXPATHLEN+1];
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000506 n = fread(buf, 1, MAXPATHLEN, f);
507 buf[n] = '\0';
508 fclose(f);
509 decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
510 if (decoded != NULL) {
Victor Stinner47f637c2010-11-10 14:12:20 +0000511 Py_ssize_t k;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000512 k = PyUnicode_AsWideChar(decoded,
Victor Stinnere406ef42010-08-14 00:07:14 +0000513 rel_builddir_path, MAXPATHLEN);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000514 Py_DECREF(decoded);
Victor Stinner47f637c2010-11-10 14:12:20 +0000515 if (k >= 0) {
516 rel_builddir_path[k] = L'\0';
Victor Stinner9316ee42017-11-25 03:17:57 +0100517 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
518 exec_prefix[MAXPATHLEN] = L'\0';
519 joinpath(exec_prefix, rel_builddir_path);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000520 return -1;
521 }
522 }
523 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000524 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000525
Fred Drakeedabdc12000-07-08 06:16:37 +0000526 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100527 copy_absolute(exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000528 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100529 n = wcslen(exec_prefix);
530 joinpath(exec_prefix, calculate->lib_python);
531 joinpath(exec_prefix, L"lib-dynload");
532 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000533 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100534 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100535 exec_prefix[n] = L'\0';
536 reduce(exec_prefix);
537 } while (exec_prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000538
Fred Drakeedabdc12000-07-08 06:16:37 +0000539 /* Look at configure's EXEC_PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100540 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
541 exec_prefix[MAXPATHLEN] = L'\0';
542 joinpath(exec_prefix, calculate->lib_python);
543 joinpath(exec_prefix, L"lib-dynload");
544 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000545 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100546 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000547
Fred Drakeedabdc12000-07-08 06:16:37 +0000548 /* Fail */
549 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000550}
551
Guido van Rossum305e5d01997-04-11 17:18:45 +0000552
Victor Stinner0327bde2017-11-23 17:03:20 +0100553static void
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100554calculate_exec_prefix(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100555 PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100556{
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100557 calculate->exec_prefix_found = search_for_exec_prefix(core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100558 calculate,
559 exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100560 if (!calculate->exec_prefix_found) {
561 if (!Py_FrozenFlag) {
562 fprintf(stderr,
563 "Could not find platform dependent libraries <exec_prefix>\n");
564 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100565 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
566 joinpath(exec_prefix, L"lib/lib-dynload");
Victor Stinner0327bde2017-11-23 17:03:20 +0100567 }
568 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
569}
570
571
572static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100573calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100574{
575 if (calculate->exec_prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100576 reduce(exec_prefix);
577 reduce(exec_prefix);
578 reduce(exec_prefix);
579 if (!exec_prefix[0]) {
580 wcscpy(exec_prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100581 }
582 }
583 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100584 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100585 }
586}
587
588
Victor Stinner9316ee42017-11-25 03:17:57 +0100589static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100590calculate_program_full_path(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100591 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100592{
Victor Stinnerb64de462017-12-01 18:27:09 +0100593 wchar_t program_full_path[MAXPATHLEN+1];
594 memset(program_full_path, 0, sizeof(program_full_path));
Victor Stinner9316ee42017-11-25 03:17:57 +0100595
Victor Stinnerb9197952017-11-23 19:02:04 +0100596#ifdef __APPLE__
597#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
598 uint32_t nsexeclength = MAXPATHLEN;
599#else
600 unsigned long nsexeclength = MAXPATHLEN;
601#endif
602 char execpath[MAXPATHLEN+1];
603#endif
604
Victor Stinner0327bde2017-11-23 17:03:20 +0100605 /* If there is no slash in the argv0 path, then we have to
606 * assume python is on the user's $PATH, since there's no
607 * other way to find a directory to start the search from. If
608 * $PATH isn't exported, you lose.
609 */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100610 if (wcschr(core_config->program_name, SEP)) {
611 wcsncpy(program_full_path, core_config->program_name, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100612 }
Jack Jansen1afd4802004-06-03 14:33:03 +0000613#ifdef __APPLE__
Jack Jansen1afd4802004-06-03 14:33:03 +0000614 /* On Mac OS X, if a script uses an interpreter of the form
615 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
616 * as argv[0], which falls through to the $PATH search below.
617 * If /opt/python2.3/bin isn't in your path, or is near the end,
618 * this algorithm may incorrectly find /usr/bin/python. To work
619 * around this, we can use _NSGetExecutablePath to get a better
620 * hint of what the intended interpreter was, although this
621 * will fail if a relative path was used. but in that case,
622 * absolutize() should help us out below
623 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100624 else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
625 execpath[0] == SEP)
626 {
Victor Stinner31a83932017-12-04 13:39:15 +0100627 size_t len;
628 wchar_t *path = Py_DecodeLocale(execpath, &len);
629 if (path == NULL) {
630 return DECODE_LOCALE_ERR("executable path", len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 }
Victor Stinner31a83932017-12-04 13:39:15 +0100632 wcsncpy(program_full_path, path, MAXPATHLEN);
633 PyMem_RawFree(path);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000634 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000635#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100636 else if (calculate->path_env) {
637 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000638 while (1) {
639 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000640
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000641 if (delim) {
642 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100643 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000644 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100645 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100646 wcsncpy(program_full_path, path, len);
647 program_full_path[len] = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000648 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100649 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100650 wcsncpy(program_full_path, path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100651 }
Jack Jansen55070f52001-12-02 23:56:28 +0000652
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100653 joinpath(program_full_path, core_config->program_name);
Victor Stinnerb64de462017-12-01 18:27:09 +0100654 if (isxfile(program_full_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000655 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100656 }
Jack Jansen55070f52001-12-02 23:56:28 +0000657
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000658 if (!delim) {
Victor Stinnerb64de462017-12-01 18:27:09 +0100659 program_full_path[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000660 break;
661 }
662 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000664 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100665 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100666 program_full_path[0] = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100667 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100668 if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
669 absolutize(program_full_path);
Victor Stinner0327bde2017-11-23 17:03:20 +0100670 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100671
Victor Stinnerb64de462017-12-01 18:27:09 +0100672 config->program_full_path = _PyMem_RawWcsdup(program_full_path);
673 if (config->program_full_path == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100674 return _Py_INIT_NO_MEMORY();
675 }
676 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100677}
678
679
Victor Stinner9316ee42017-11-25 03:17:57 +0100680static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100681calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path)
Victor Stinner0327bde2017-11-23 17:03:20 +0100682{
Victor Stinnerb64de462017-12-01 18:27:09 +0100683 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100684 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000685
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000686#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100687 NSModule pythonModule;
688
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000689 /* On Mac OS X we have a special case if we're running from a framework.
690 ** This is because the python home should be set relative to the library,
691 ** which is in the framework, not relative to the executable, which may
692 ** be outside of the framework. Except when we're in the build directory...
693 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000694 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
695 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100696 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100697 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000698 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000699 /* See if we might be in the build directory. The framework in the
700 ** build directory is incomplete, it only has the .dylib and a few
701 ** needed symlinks, it doesn't have the Lib directories and such.
702 ** If we're running with the framework from the build directory we must
703 ** be running the interpreter in the build directory, so we use the
704 ** build-directory-specific logic to find Lib and such.
705 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100706 size_t len;
707 wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100708 if (wbuf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100709 return DECODE_LOCALE_ERR("framework location", len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100710 }
711
Victor Stinner0327bde2017-11-23 17:03:20 +0100712 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
713 reduce(calculate->argv0_path);
714 joinpath(calculate->argv0_path, calculate->lib_python);
715 joinpath(calculate->argv0_path, LANDMARK);
716 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000717 /* We are in the build directory so use the name of the
718 executable - we know that the absolute path is passed */
Victor Stinnerb64de462017-12-01 18:27:09 +0100719 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000720 }
721 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100722 /* Use the location of the library as the program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100723 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000724 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200725 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000726 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000727#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000728
Guido van Rossum305e5d01997-04-11 17:18:45 +0000729#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100730 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinnerb64de462017-12-01 18:27:09 +0100731 int linklen = _Py_wreadlink(program_full_path, tmpbuffer, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100732 while (linklen != -1) {
733 if (tmpbuffer[0] == SEP) {
734 /* tmpbuffer should never be longer than MAXPATHLEN,
735 but extra check does not hurt */
736 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000737 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100738 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100739 /* Interpret relative to program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100740 reduce(calculate->argv0_path);
741 joinpath(calculate->argv0_path, tmpbuffer);
742 }
743 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000744 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000745#endif /* HAVE_READLINK */
746
Victor Stinner0327bde2017-11-23 17:03:20 +0100747 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000748 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100749 MAXPATHLEN bytes long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100750 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100751}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000752
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100753
Victor Stinner0327bde2017-11-23 17:03:20 +0100754/* Search for an "pyvenv.cfg" environment configuration file, first in the
755 executable's directory and then in the parent directory.
756 If found, open it for use when searching for prefixes.
757*/
758static void
759calculate_read_pyenv(PyCalculatePath *calculate)
760{
761 wchar_t tmpbuffer[MAXPATHLEN+1];
762 wchar_t *env_cfg = L"pyvenv.cfg";
763 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100764
Victor Stinner0327bde2017-11-23 17:03:20 +0100765 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100766
Victor Stinner0327bde2017-11-23 17:03:20 +0100767 joinpath(tmpbuffer, env_cfg);
768 env_file = _Py_wfopen(tmpbuffer, L"r");
769 if (env_file == NULL) {
770 errno = 0;
771
772 reduce(tmpbuffer);
773 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100774 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100775
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100776 env_file = _Py_wfopen(tmpbuffer, L"r");
777 if (env_file == NULL) {
778 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100779 }
780 }
781
Victor Stinner0327bde2017-11-23 17:03:20 +0100782 if (env_file == NULL) {
783 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000784 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000785
Victor Stinner0327bde2017-11-23 17:03:20 +0100786 /* Look for a 'home' variable and set argv0_path to it, if found */
787 if (find_env_config_value(env_file, L"home", tmpbuffer)) {
788 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000789 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100790 fclose(env_file);
791}
Just van Rossum52e14d62002-12-30 22:08:05 +0000792
Guido van Rossum305e5d01997-04-11 17:18:45 +0000793
Victor Stinner0327bde2017-11-23 17:03:20 +0100794static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100795calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100796{
Victor Stinner9316ee42017-11-25 03:17:57 +0100797 wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100798 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000799
Victor Stinner0327bde2017-11-23 17:03:20 +0100800 if (calculate->prefix_found > 0) {
801 /* Use the reduced prefix returned by Py_GetPrefix() */
802 reduce(calculate->zip_path);
803 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100804 }
805 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100806 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
807 }
808 joinpath(calculate->zip_path, L"lib/python00.zip");
809
810 /* Replace "00" with version */
811 size_t bufsz = wcslen(calculate->zip_path);
812 calculate->zip_path[bufsz - 6] = VERSION[0];
813 calculate->zip_path[bufsz - 5] = VERSION[2];
814}
815
816
Victor Stinner9316ee42017-11-25 03:17:57 +0100817static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100818calculate_module_search_path(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100819 PyCalculatePath *calculate,
Victor Stinner9316ee42017-11-25 03:17:57 +0100820 const wchar_t *prefix, const wchar_t *exec_prefix,
Victor Stinnerb64de462017-12-01 18:27:09 +0100821 _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100822{
823 /* Calculate size of return buffer */
824 size_t bufsz = 0;
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100825 if (core_config->module_search_path_env != NULL) {
826 bufsz += wcslen(core_config->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000827 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000828
Victor Stinner0327bde2017-11-23 17:03:20 +0100829 wchar_t *defpath = calculate->pythonpath;
Victor Stinner9316ee42017-11-25 03:17:57 +0100830 size_t prefixsz = wcslen(prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000831 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000832 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000833
Victor Stinner0327bde2017-11-23 17:03:20 +0100834 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000835 /* Paths are relative to prefix */
836 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100837 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000838
Victor Stinner0327bde2017-11-23 17:03:20 +0100839 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000840 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100841 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000842 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000843 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000844 break;
845 }
846 defpath = delim + 1;
847 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000848
Victor Stinner0327bde2017-11-23 17:03:20 +0100849 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner9316ee42017-11-25 03:17:57 +0100850 bufsz += wcslen(exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000851
Victor Stinner0327bde2017-11-23 17:03:20 +0100852 /* Allocate the buffer */
853 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000854 if (buf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100855 return _Py_INIT_NO_MEMORY();
Fred Drakeedabdc12000-07-08 06:16:37 +0000856 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100857 buf[0] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000858
Victor Stinner72967a42013-11-16 01:22:04 +0100859 /* Run-time value of $PYTHONPATH goes first */
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100860 if (core_config->module_search_path_env) {
861 wcscpy(buf, core_config->module_search_path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100862 wcscat(buf, delimiter);
Fred Drakeedabdc12000-07-08 06:16:37 +0000863 }
Victor Stinner72967a42013-11-16 01:22:04 +0100864
865 /* Next is the default zip path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100866 wcscat(buf, calculate->zip_path);
Victor Stinner72967a42013-11-16 01:22:04 +0100867 wcscat(buf, delimiter);
868
869 /* Next goes merge of compile-time $PYTHONPATH with
870 * dynamically located prefix.
871 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100872 defpath = calculate->pythonpath;
Victor Stinner72967a42013-11-16 01:22:04 +0100873 while (1) {
874 wchar_t *delim = wcschr(defpath, DELIM);
875
876 if (defpath[0] != SEP) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100877 wcscat(buf, prefix);
878 if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
Victor Stinner0327bde2017-11-23 17:03:20 +0100879 defpath[0] != (delim ? DELIM : L'\0'))
880 {
881 /* not empty */
Serhiy Storchaka62e32d62016-11-11 12:05:01 +0200882 wcscat(buf, separator);
883 }
Victor Stinner72967a42013-11-16 01:22:04 +0100884 }
885
886 if (delim) {
887 size_t len = delim - defpath + 1;
888 size_t end = wcslen(buf) + len;
889 wcsncat(buf, defpath, len);
Victor Stinner9316ee42017-11-25 03:17:57 +0100890 buf[end] = '\0';
Victor Stinner72967a42013-11-16 01:22:04 +0100891 }
892 else {
893 wcscat(buf, defpath);
894 break;
895 }
896 defpath = delim + 1;
897 }
898 wcscat(buf, delimiter);
899
900 /* Finally, on goes the directory for dynamic-load modules */
Victor Stinner9316ee42017-11-25 03:17:57 +0100901 wcscat(buf, exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100902
Victor Stinner9316ee42017-11-25 03:17:57 +0100903 config->module_search_path = buf;
904 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100905}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000906
Victor Stinner0327bde2017-11-23 17:03:20 +0100907
Victor Stinner0327bde2017-11-23 17:03:20 +0100908static _PyInitError
909calculate_init(PyCalculatePath *calculate,
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100910 const _PyCoreConfig *core_config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100911{
Victor Stinner0327bde2017-11-23 17:03:20 +0100912 size_t len;
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200913 const char *path = getenv("PATH");
Victor Stinner0327bde2017-11-23 17:03:20 +0100914 if (path) {
915 calculate->path_env = Py_DecodeLocale(path, &len);
916 if (!calculate->path_env) {
Victor Stinner46972b72017-11-24 22:55:40 +0100917 return DECODE_LOCALE_ERR("PATH environment variable", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100918 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000919 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000920
Victor Stinner0327bde2017-11-23 17:03:20 +0100921 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
922 if (!calculate->pythonpath) {
Victor Stinner46972b72017-11-24 22:55:40 +0100923 return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100924 }
925 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
926 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100927 return DECODE_LOCALE_ERR("PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100928 }
929 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
930 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100931 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100932 }
933 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
934 if (!calculate->lib_python) {
Victor Stinner46972b72017-11-24 22:55:40 +0100935 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100936 }
937 return _Py_INIT_OK();
938}
939
940
941static void
942calculate_free(PyCalculatePath *calculate)
943{
944 PyMem_RawFree(calculate->pythonpath);
945 PyMem_RawFree(calculate->prefix);
946 PyMem_RawFree(calculate->exec_prefix);
947 PyMem_RawFree(calculate->lib_python);
948 PyMem_RawFree(calculate->path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100949}
950
951
Victor Stinner9316ee42017-11-25 03:17:57 +0100952static _PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100953calculate_path_impl(const _PyCoreConfig *core_config,
Victor Stinner31a83932017-12-04 13:39:15 +0100954 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100955{
Victor Stinner31a83932017-12-04 13:39:15 +0100956 _PyInitError err;
957
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100958 err = calculate_program_full_path(core_config, calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100959 if (_Py_INIT_FAILED(err)) {
960 return err;
961 }
962
Victor Stinnerb64de462017-12-01 18:27:09 +0100963 err = calculate_argv0_path(calculate, config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100964 if (_Py_INIT_FAILED(err)) {
965 return err;
966 }
967
Victor Stinner0327bde2017-11-23 17:03:20 +0100968 calculate_read_pyenv(calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100969
970 wchar_t prefix[MAXPATHLEN+1];
971 memset(prefix, 0, sizeof(prefix));
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100972 calculate_prefix(core_config, calculate, prefix);
Victor Stinner9316ee42017-11-25 03:17:57 +0100973
974 calculate_zip_path(calculate, prefix);
975
976 wchar_t exec_prefix[MAXPATHLEN+1];
977 memset(exec_prefix, 0, sizeof(exec_prefix));
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100978 calculate_exec_prefix(core_config, calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100979
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100980 if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
981 !Py_FrozenFlag)
982 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100983 fprintf(stderr,
984 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
985 }
986
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100987 err = calculate_module_search_path(core_config, calculate,
Victor Stinner31a83932017-12-04 13:39:15 +0100988 prefix, exec_prefix, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100989 if (_Py_INIT_FAILED(err)) {
990 return err;
991 }
992
993 calculate_reduce_prefix(calculate, prefix);
994
995 config->prefix = _PyMem_RawWcsdup(prefix);
996 if (config->prefix == NULL) {
997 return _Py_INIT_NO_MEMORY();
998 }
999
1000 calculate_reduce_exec_prefix(calculate, exec_prefix);
1001
1002 config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
1003 if (config->exec_prefix == NULL) {
1004 return _Py_INIT_NO_MEMORY();
1005 }
1006
1007 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001008}
1009
1010
Serhiy Storchaka13badcb2017-12-02 21:36:00 +02001011_PyInitError
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +01001012_PyPathConfig_Calculate(_PyPathConfig *config, const _PyCoreConfig *core_config)
Serhiy Storchaka13badcb2017-12-02 21:36:00 +02001013{
Victor Stinner0327bde2017-11-23 17:03:20 +01001014 PyCalculatePath calculate;
1015 memset(&calculate, 0, sizeof(calculate));
1016
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +01001017 _PyInitError err = calculate_init(&calculate, core_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001018 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001019 goto done;
Victor Stinner0327bde2017-11-23 17:03:20 +01001020 }
1021
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +01001022 err = calculate_path_impl(core_config, &calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +01001023 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001024 goto done;
1025 }
1026
Victor Stinner9316ee42017-11-25 03:17:57 +01001027 err = _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001028
Victor Stinner9316ee42017-11-25 03:17:57 +01001029done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001030 calculate_free(&calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +01001031 return err;
1032}
Victor Stinner46972b72017-11-24 22:55:40 +01001033
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001034#ifdef __cplusplus
1035}
1036#endif