blob: 48bdd0f21daca770613070cb4568304c135defb0 [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"
4#include "osdefs.h"
5
Guido van Rossum305e5d01997-04-11 17:18:45 +00006#include <sys/types.h>
Guido van Rossum21f84971997-06-02 22:18:31 +00007#include <string.h>
Guido van Rossum667d7041995-08-04 04:20:48 +00008
Brett Cannonf6af76d2004-06-26 04:03:06 +00009#ifdef __APPLE__
Victor Stinner0327bde2017-11-23 17:03:20 +010010# include <mach-o/dyld.h>
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011#endif
12
Guido van Rossum305e5d01997-04-11 17:18:45 +000013/* Search in some common locations for the associated Python libraries.
14 *
15 * Two directories must be found, the platform independent directory
Barry Warsaw90126031997-04-11 20:27:03 +000016 * (prefix), containing the common .py and .pyc files, and the platform
17 * dependent directory (exec_prefix), containing the shared library
18 * modules. Note that prefix and exec_prefix can be the same directory,
19 * but for some installations, they are different.
Guido van Rossum305e5d01997-04-11 17:18:45 +000020 *
Barry Warsaw90126031997-04-11 20:27:03 +000021 * Py_GetPath() carries out separate searches for prefix and exec_prefix.
22 * Each search tries a number of different locations until a ``landmark''
23 * file or directory is found. If no prefix or exec_prefix is found, a
24 * warning message is issued and the preprocessor defined PREFIX and
25 * EXEC_PREFIX are used (even though they will not work); python carries on
26 * as best as is possible, but most imports will fail.
Guido van Rossum305e5d01997-04-11 17:18:45 +000027 *
28 * Before any searches are done, the location of the executable is
Guido van Rossumd8faa362007-04-27 19:54:29 +000029 * determined. If argv[0] has one or more slashes in it, it is used
Barry Warsaw90126031997-04-11 20:27:03 +000030 * unchanged. Otherwise, it must have been invoked from the shell's path,
31 * so we search $PATH for the named executable and use that. If the
32 * executable was not found on $PATH (or there was no $PATH environment
33 * variable), the original argv[0] string is used.
Guido van Rossum305e5d01997-04-11 17:18:45 +000034 *
Barry Warsaw90126031997-04-11 20:27:03 +000035 * Next, the executable location is examined to see if it is a symbolic
36 * link. If so, the link is chased (correctly interpreting a relative
37 * pathname if one is found) and the directory of the link target is used.
Guido van Rossum305e5d01997-04-11 17:18:45 +000038 *
Barry Warsaw90126031997-04-11 20:27:03 +000039 * Finally, argv0_path is set to the directory containing the executable
40 * (i.e. the last component is stripped).
Guido van Rossum305e5d01997-04-11 17:18:45 +000041 *
Barry Warsaw90126031997-04-11 20:27:03 +000042 * With argv0_path in hand, we perform a number of steps. The same steps
43 * are performed for prefix and for exec_prefix, but with a different
44 * landmark.
Guido van Rossum305e5d01997-04-11 17:18:45 +000045 *
46 * Step 1. Are we running python out of the build directory? This is
47 * checked by looking for a different kind of landmark relative to
Barry Warsaw90126031997-04-11 20:27:03 +000048 * argv0_path. For prefix, the landmark's path is derived from the VPATH
49 * preprocessor variable (taking into account that its value is almost, but
50 * not quite, what we need). For exec_prefix, the landmark is
Antoine Pitroueba57b62010-08-14 12:33:18 +000051 * pybuilddir.txt. If the landmark is found, we're done.
Guido van Rossum305e5d01997-04-11 17:18:45 +000052 *
53 * For the remaining steps, the prefix landmark will always be
Jeremy Hylton847a9962000-05-26 21:49:07 +000054 * lib/python$VERSION/os.py and the exec_prefix will always be
Guido van Rossum266033e1997-10-20 23:20:32 +000055 * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
Barry Warsaw90126031997-04-11 20:27:03 +000056 * number as supplied by the Makefile. Note that this means that no more
57 * build directory checking is performed; if the first step did not find
58 * the landmarks, the assumption is that python is running from an
59 * installed setup.
Guido van Rossum305e5d01997-04-11 17:18:45 +000060 *
61 * Step 2. See if the $PYTHONHOME environment variable points to the
Barry Warsaw90126031997-04-11 20:27:03 +000062 * installed location of the Python libraries. If $PYTHONHOME is set, then
63 * it points to prefix and exec_prefix. $PYTHONHOME can be a single
64 * directory, which is used for both, or the prefix and exec_prefix
65 * directories separated by a colon.
Guido van Rossum305e5d01997-04-11 17:18:45 +000066 *
67 * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
Barry Warsaw90126031997-04-11 20:27:03 +000068 * backtracking up the path until it is exhausted. This is the most common
69 * step to succeed. Note that if prefix and exec_prefix are different,
70 * exec_prefix is more likely to be found; however if exec_prefix is a
71 * subdirectory of prefix, both will be found.
Guido van Rossum305e5d01997-04-11 17:18:45 +000072 *
Barry Warsaw90126031997-04-11 20:27:03 +000073 * Step 4. Search the directories pointed to by the preprocessor variables
74 * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be
75 * passed in as options to the configure script.
Guido van Rossum305e5d01997-04-11 17:18:45 +000076 *
Barry Warsaw90126031997-04-11 20:27:03 +000077 * That's it!
78 *
79 * Well, almost. Once we have determined prefix and exec_prefix, the
Thomas Wouters7e474022000-07-16 12:04:32 +000080 * preprocessor variable PYTHONPATH is used to construct a path. Each
Barry Warsaw90126031997-04-11 20:27:03 +000081 * relative path on PYTHONPATH is prefixed with prefix. Then the directory
82 * containing the shared library modules is appended. The environment
83 * variable $PYTHONPATH is inserted in front of it all. Finally, the
84 * prefix and exec_prefix globals are tweaked so they reflect the values
85 * expected by other code, by stripping the "lib/python$VERSION/..." stuff
86 * off. If either points to the build directory, the globals are reset to
87 * the corresponding preprocessor variables (so sys.prefix will reflect the
88 * installation location, even though sys.path points into the build
89 * directory). This seems to make more sense given that currently the only
90 * known use of sys.prefix and sys.exec_prefix is for the ILU installation
91 * process to find the installed Python tree.
Antoine Pitroueba57b62010-08-14 12:33:18 +000092 *
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +000093 * An embedding application can use Py_SetPath() to override all of
94 * these authomatic path computations.
95 *
Antoine Pitroueba57b62010-08-14 12:33:18 +000096 * NOTE: Windows MSVC builds use PC/getpathp.c instead!
Barry Warsaw90126031997-04-11 20:27:03 +000097 */
Guido van Rossum305e5d01997-04-11 17:18:45 +000098
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000099#ifdef __cplusplus
Victor Stinner0327bde2017-11-23 17:03:20 +0100100extern "C" {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000101#endif
102
103
Benjamin Petersonf5854142016-06-02 12:41:35 -0700104#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH)
105#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined"
Guido van Rossum305e5d01997-04-11 17:18:45 +0000106#endif
Guido van Rossum667d7041995-08-04 04:20:48 +0000107
Guido van Rossum305e5d01997-04-11 17:18:45 +0000108#ifndef LANDMARK
Martin v. Löwis790465f2008-04-05 20:41:37 +0000109#define LANDMARK L"os.py"
Guido van Rossum305e5d01997-04-11 17:18:45 +0000110#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000111
Victor Stinner0327bde2017-11-23 17:03:20 +0100112typedef struct {
113 wchar_t prefix[MAXPATHLEN+1];
114 wchar_t exec_prefix[MAXPATHLEN+1];
115 wchar_t progpath[MAXPATHLEN+1];
116 wchar_t *module_search_path;
117} PyPathConfig;
118
119typedef struct {
120 wchar_t *path_env; /* PATH environment variable */
121 wchar_t *home; /* PYTHONHOME environment variable */
122 wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
123 wchar_t *module_search_path_buffer;
124
125 wchar_t *prog; /* Program name */
126 wchar_t *pythonpath; /* PYTHONPATH define */
127 wchar_t *prefix; /* PREFIX define */
128 wchar_t *exec_prefix; /* EXEC_PREFIX define */
129
130 wchar_t *lib_python; /* "lib/pythonX.Y" */
131 wchar_t argv0_path[MAXPATHLEN+1];
132 wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */
133
134 int prefix_found; /* found platform independent libraries? */
135 int exec_prefix_found; /* found the platform dependent libraries? */
136} PyCalculatePath;
137
138static const wchar_t delimiter[2] = {DELIM, '\0'};
139static const wchar_t separator[2] = {SEP, '\0'};
140static PyPathConfig path_config = {.module_search_path = NULL};
141
Martin v. Löwis790465f2008-04-05 20:41:37 +0000142
Victor Stinner91afbb62015-03-24 12:16:28 +0100143/* Get file status. Encode the path to the locale encoding. */
Victor Stinner91afbb62015-03-24 12:16:28 +0100144static int
145_Py_wstat(const wchar_t* path, struct stat *buf)
146{
147 int err;
148 char *fname;
149 fname = Py_EncodeLocale(path, NULL);
150 if (fname == NULL) {
151 errno = EINVAL;
152 return -1;
153 }
154 err = stat(fname, buf);
155 PyMem_Free(fname);
156 return err;
157}
158
Victor Stinner0327bde2017-11-23 17:03:20 +0100159
Guido van Rossum305e5d01997-04-11 17:18:45 +0000160static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000161reduce(wchar_t *dir)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000162{
Martin v. Löwis790465f2008-04-05 20:41:37 +0000163 size_t i = wcslen(dir);
Fred Drakeedabdc12000-07-08 06:16:37 +0000164 while (i > 0 && dir[i] != SEP)
165 --i;
166 dir[i] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000167}
Guido van Rossumd29806c1998-01-19 22:06:22 +0000168
Victor Stinner0327bde2017-11-23 17:03:20 +0100169
Guido van Rossum305e5d01997-04-11 17:18:45 +0000170static int
Martin v. Löwis790465f2008-04-05 20:41:37 +0000171isfile(wchar_t *filename) /* Is file, not directory */
Guido van Rossum305e5d01997-04-11 17:18:45 +0000172{
Fred Drakeedabdc12000-07-08 06:16:37 +0000173 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100174 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000175 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100176 }
177 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000178 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100179 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000180 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000181}
182
183
184static int
Brett Cannonf299abd2015-04-13 14:21:02 -0400185ismodule(wchar_t *filename) /* Is module -- check for .pyc too */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000186{
Victor Stinner0327bde2017-11-23 17:03:20 +0100187 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000188 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100189 }
Guido van Rossumd29806c1998-01-19 22:06:22 +0000190
Fred Drakeedabdc12000-07-08 06:16:37 +0000191 /* Check for the compiled version of prefix. */
Martin v. Löwis790465f2008-04-05 20:41:37 +0000192 if (wcslen(filename) < MAXPATHLEN) {
Brett Cannonf299abd2015-04-13 14:21:02 -0400193 wcscat(filename, L"c");
Victor Stinner0327bde2017-11-23 17:03:20 +0100194 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000195 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100196 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000197 }
198 return 0;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000199}
200
201
Victor Stinner0327bde2017-11-23 17:03:20 +0100202/* Is executable file */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000203static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100204isxfile(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000205{
Fred Drakeedabdc12000-07-08 06:16:37 +0000206 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100207 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000208 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100209 }
210 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000211 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100212 }
213 if ((buf.st_mode & 0111) == 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000214 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100215 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000216 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000217}
218
219
Victor Stinner0327bde2017-11-23 17:03:20 +0100220/* Is directory */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000221static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100222isdir(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000223{
Fred Drakeedabdc12000-07-08 06:16:37 +0000224 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100225 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000226 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100227 }
228 if (!S_ISDIR(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000229 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100230 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000231 return 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000232}
233
234
Tim Petersec8c5a92004-08-08 01:00:47 +0000235/* Add a path component, by appending stuff to buffer.
236 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
237 NUL-terminated string with no more than MAXPATHLEN characters (not counting
238 the trailing NUL). It's a fatal error if it contains a string longer than
239 that (callers must be careful!). If these requirements are met, it's
240 guaranteed that buffer will still be a NUL-terminated string with no more
241 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
242 stuff as fits will be appended.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000243*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000244static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000245joinpath(wchar_t *buffer, wchar_t *stuff)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000246{
Fred Drakeedabdc12000-07-08 06:16:37 +0000247 size_t n, k;
Victor Stinner0327bde2017-11-23 17:03:20 +0100248 if (stuff[0] == SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000249 n = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100250 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000251 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000252 n = wcslen(buffer);
Victor Stinner0327bde2017-11-23 17:03:20 +0100253 if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000254 buffer[n++] = SEP;
Victor Stinner0327bde2017-11-23 17:03:20 +0100255 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000256 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100257 if (n > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 Py_FatalError("buffer overflow in getpath.c's joinpath()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100259 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000260 k = wcslen(stuff);
Victor Stinner0327bde2017-11-23 17:03:20 +0100261 if (n + k > MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000262 k = MAXPATHLEN - n;
Victor Stinner0327bde2017-11-23 17:03:20 +0100263 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000264 wcsncpy(buffer+n, stuff, k);
Fred Drakeedabdc12000-07-08 06:16:37 +0000265 buffer[n+k] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000266}
267
Victor Stinner0327bde2017-11-23 17:03:20 +0100268
Guido van Rossume296ced2001-09-28 20:00:29 +0000269/* copy_absolute requires that path be allocated at least
270 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000271static void
Victor Stinnerf4061da2010-10-14 12:37:19 +0000272copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000273{
Victor Stinner0327bde2017-11-23 17:03:20 +0100274 if (p[0] == SEP) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000275 wcscpy(path, p);
Victor Stinner0327bde2017-11-23 17:03:20 +0100276 }
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000277 else {
Victor Stinnerf4061da2010-10-14 12:37:19 +0000278 if (!_Py_wgetcwd(path, pathlen)) {
Victor Stinner4f3abb02010-10-07 23:29:18 +0000279 /* unable to get the current directory */
280 wcscpy(path, p);
281 return;
282 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100283 if (p[0] == '.' && p[1] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000284 p += 2;
Victor Stinner0327bde2017-11-23 17:03:20 +0100285 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000286 joinpath(path, p);
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000287 }
288}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000289
Victor Stinner0327bde2017-11-23 17:03:20 +0100290
Guido van Rossume296ced2001-09-28 20:00:29 +0000291/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
292static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000293absolutize(wchar_t *path)
Guido van Rossume296ced2001-09-28 20:00:29 +0000294{
Victor Stinnerf4061da2010-10-14 12:37:19 +0000295 wchar_t buffer[MAXPATHLEN+1];
Guido van Rossume296ced2001-09-28 20:00:29 +0000296
Victor Stinner0327bde2017-11-23 17:03:20 +0100297 if (path[0] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000298 return;
Victor Stinner0327bde2017-11-23 17:03:20 +0100299 }
Victor Stinnerf4061da2010-10-14 12:37:19 +0000300 copy_absolute(buffer, path, MAXPATHLEN+1);
Martin v. Löwis790465f2008-04-05 20:41:37 +0000301 wcscpy(path, buffer);
Guido van Rossume296ced2001-09-28 20:00:29 +0000302}
303
Victor Stinner0327bde2017-11-23 17:03:20 +0100304
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100305/* search for a prefix value in an environment file. If found, copy it
306 to the provided buffer, which is expected to be no more than MAXPATHLEN
307 bytes long.
308*/
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100309static int
310find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
311{
312 int result = 0; /* meaning not found */
313 char buffer[MAXPATHLEN*2+1]; /* allow extra for key, '=', etc. */
314
315 fseek(env_file, 0, SEEK_SET);
316 while (!feof(env_file)) {
317 char * p = fgets(buffer, MAXPATHLEN*2, env_file);
318 wchar_t tmpbuffer[MAXPATHLEN*2+1];
319 PyObject * decoded;
320 int n;
321
Victor Stinner0327bde2017-11-23 17:03:20 +0100322 if (p == NULL) {
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100323 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100324 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100325 n = strlen(p);
326 if (p[n - 1] != '\n') {
327 /* line has overflowed - bail */
328 break;
329 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100330 if (p[0] == '#') {
331 /* Comment - skip */
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100332 continue;
Victor Stinner0327bde2017-11-23 17:03:20 +0100333 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100334 decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
335 if (decoded != NULL) {
336 Py_ssize_t k;
337 wchar_t * state;
338 k = PyUnicode_AsWideChar(decoded,
339 tmpbuffer, MAXPATHLEN * 2);
340 Py_DECREF(decoded);
341 if (k >= 0) {
342 wchar_t * tok = wcstok(tmpbuffer, L" \t\r\n", &state);
343 if ((tok != NULL) && !wcscmp(tok, key)) {
344 tok = wcstok(NULL, L" \t", &state);
345 if ((tok != NULL) && !wcscmp(tok, L"=")) {
346 tok = wcstok(NULL, L"\r\n", &state);
347 if (tok != NULL) {
348 wcsncpy(value, tok, MAXPATHLEN);
349 result = 1;
350 break;
351 }
352 }
353 }
354 }
355 }
356 }
357 return result;
358}
359
Victor Stinner0327bde2017-11-23 17:03:20 +0100360
Guido van Rossume296ced2001-09-28 20:00:29 +0000361/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000362 bytes long.
363*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000364static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100365search_for_prefix(PyCalculatePath *calculate, PyPathConfig *config)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000366{
Fred Drakeedabdc12000-07-08 06:16:37 +0000367 size_t n;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000368 wchar_t *vpath;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000369
Fred Drakeedabdc12000-07-08 06:16:37 +0000370 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinner0327bde2017-11-23 17:03:20 +0100371 if (calculate->home) {
372 wcsncpy(config->prefix, calculate->home, MAXPATHLEN);
373 config->prefix[MAXPATHLEN] = L'\0';
374 wchar_t *delim = wcschr(config->prefix, DELIM);
375 if (delim) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000376 *delim = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100377 }
378 joinpath(config->prefix, calculate->lib_python);
379 joinpath(config->prefix, LANDMARK);
Fred Drakeedabdc12000-07-08 06:16:37 +0000380 return 1;
381 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000382
Fred Drakeedabdc12000-07-08 06:16:37 +0000383 /* Check to see if argv[0] is in the build directory */
Victor Stinner0327bde2017-11-23 17:03:20 +0100384 wcsncpy(config->prefix, calculate->argv0_path, MAXPATHLEN);
385 config->prefix[MAXPATHLEN] = L'\0';
386 joinpath(config->prefix, L"Modules/Setup");
387 if (isfile(config->prefix)) {
Neil Schemenauer6cf07022001-01-24 17:13:11 +0000388 /* Check VPATH to see if argv0_path is in the build directory. */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200389 vpath = Py_DecodeLocale(VPATH, NULL);
Victor Stinner21582312010-10-23 00:13:28 +0000390 if (vpath != NULL) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100391 wcsncpy(config->prefix, calculate->argv0_path, MAXPATHLEN);
392 config->prefix[MAXPATHLEN] = L'\0';
393 joinpath(config->prefix, vpath);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200394 PyMem_RawFree(vpath);
Victor Stinner0327bde2017-11-23 17:03:20 +0100395 joinpath(config->prefix, L"Lib");
396 joinpath(config->prefix, LANDMARK);
397 if (ismodule(config->prefix)) {
Victor Stinner21582312010-10-23 00:13:28 +0000398 return -1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100399 }
Victor Stinner21582312010-10-23 00:13:28 +0000400 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000401 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000402
Fred Drakeedabdc12000-07-08 06:16:37 +0000403 /* Search from argv0_path, until root is found */
Victor Stinner0327bde2017-11-23 17:03:20 +0100404 copy_absolute(config->prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000405 do {
Victor Stinner0327bde2017-11-23 17:03:20 +0100406 n = wcslen(config->prefix);
407 joinpath(config->prefix, calculate->lib_python);
408 joinpath(config->prefix, LANDMARK);
409 if (ismodule(config->prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000410 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100411 }
412 config->prefix[n] = L'\0';
413 reduce(config->prefix);
414 } while (config->prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000415
Fred Drakeedabdc12000-07-08 06:16:37 +0000416 /* Look at configure's PREFIX */
Victor Stinner0327bde2017-11-23 17:03:20 +0100417 wcsncpy(config->prefix, calculate->prefix, MAXPATHLEN);
418 config->prefix[MAXPATHLEN] = L'\0';
419 joinpath(config->prefix, calculate->lib_python);
420 joinpath(config->prefix, LANDMARK);
421 if (ismodule(config->prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000422 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100423 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000424
Fred Drakeedabdc12000-07-08 06:16:37 +0000425 /* Fail */
426 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000427}
428
429
Victor Stinner0327bde2017-11-23 17:03:20 +0100430static void
431calculate_prefix(PyCalculatePath *calculate, PyPathConfig *config)
432{
433 calculate->prefix_found = search_for_prefix(calculate, config);
434 if (!calculate->prefix_found) {
435 if (!Py_FrozenFlag) {
436 fprintf(stderr,
437 "Could not find platform independent libraries <prefix>\n");
438 }
439 wcsncpy(config->prefix, calculate->prefix, MAXPATHLEN);
440 joinpath(config->prefix, calculate->lib_python);
441 }
442 else {
443 reduce(config->prefix);
444 }
445}
446
447
448static void
449calculate_reduce_prefix(PyCalculatePath *calculate, PyPathConfig *config)
450{
451 /* Reduce prefix and exec_prefix to their essence,
452 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
453 * If we're loading relative to the build directory,
454 * return the compiled-in defaults instead.
455 */
456 if (calculate->prefix_found > 0) {
457 reduce(config->prefix);
458 reduce(config->prefix);
459 /* The prefix is the root directory, but reduce() chopped
460 * off the "/". */
461 if (!config->prefix[0]) {
462 wcscpy(config->prefix, separator);
463 }
464 }
465 else {
466 wcsncpy(config->prefix, calculate->prefix, MAXPATHLEN);
467 }
468}
469
470
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000471/* search_for_exec_prefix requires that argv0_path be no more than
Guido van Rossume296ced2001-09-28 20:00:29 +0000472 MAXPATHLEN bytes long.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000473*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000474static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100475search_for_exec_prefix(PyCalculatePath *calculate, PyPathConfig *config)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000476{
Fred Drakeedabdc12000-07-08 06:16:37 +0000477 size_t n;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000478
Fred Drakeedabdc12000-07-08 06:16:37 +0000479 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinner0327bde2017-11-23 17:03:20 +0100480 if (calculate->home) {
481 wchar_t *delim = wcschr(calculate->home, DELIM);
482 if (delim) {
483 wcsncpy(config->exec_prefix, delim+1, MAXPATHLEN);
484 }
485 else {
486 wcsncpy(config->exec_prefix, calculate->home, MAXPATHLEN);
487 }
488 config->exec_prefix[MAXPATHLEN] = L'\0';
489 joinpath(config->exec_prefix, calculate->lib_python);
490 joinpath(config->exec_prefix, L"lib-dynload");
Fred Drakeedabdc12000-07-08 06:16:37 +0000491 return 1;
492 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000493
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000494 /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
495 is written by setup.py and contains the relative path to the location
496 of shared library modules. */
Victor Stinner0327bde2017-11-23 17:03:20 +0100497 wcsncpy(config->exec_prefix, calculate->argv0_path, MAXPATHLEN);
498 config->exec_prefix[MAXPATHLEN] = L'\0';
499 joinpath(config->exec_prefix, L"pybuilddir.txt");
500 if (isfile(config->exec_prefix)) {
501 FILE *f = _Py_wfopen(config->exec_prefix, L"rb");
502 if (f == NULL) {
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000503 errno = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100504 }
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000505 else {
506 char buf[MAXPATHLEN+1];
507 PyObject *decoded;
508 wchar_t rel_builddir_path[MAXPATHLEN+1];
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000509 n = fread(buf, 1, MAXPATHLEN, f);
510 buf[n] = '\0';
511 fclose(f);
512 decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
513 if (decoded != NULL) {
Victor Stinner47f637c2010-11-10 14:12:20 +0000514 Py_ssize_t k;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000515 k = PyUnicode_AsWideChar(decoded,
Victor Stinnere406ef42010-08-14 00:07:14 +0000516 rel_builddir_path, MAXPATHLEN);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000517 Py_DECREF(decoded);
Victor Stinner47f637c2010-11-10 14:12:20 +0000518 if (k >= 0) {
519 rel_builddir_path[k] = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100520 wcsncpy(config->exec_prefix, calculate->argv0_path, MAXPATHLEN);
521 config->exec_prefix[MAXPATHLEN] = L'\0';
522 joinpath(config->exec_prefix, rel_builddir_path);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000523 return -1;
524 }
525 }
526 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000527 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000528
Fred Drakeedabdc12000-07-08 06:16:37 +0000529 /* Search from argv0_path, until root is found */
Victor Stinner0327bde2017-11-23 17:03:20 +0100530 copy_absolute(config->exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000531 do {
Victor Stinner0327bde2017-11-23 17:03:20 +0100532 n = wcslen(config->exec_prefix);
533 joinpath(config->exec_prefix, calculate->lib_python);
534 joinpath(config->exec_prefix, L"lib-dynload");
535 if (isdir(config->exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000536 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100537 }
538 config->exec_prefix[n] = L'\0';
539 reduce(config->exec_prefix);
540 } while (config->exec_prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000541
Fred Drakeedabdc12000-07-08 06:16:37 +0000542 /* Look at configure's EXEC_PREFIX */
Victor Stinner0327bde2017-11-23 17:03:20 +0100543 wcsncpy(config->exec_prefix, calculate->exec_prefix, MAXPATHLEN);
544 config->exec_prefix[MAXPATHLEN] = L'\0';
545 joinpath(config->exec_prefix, calculate->lib_python);
546 joinpath(config->exec_prefix, L"lib-dynload");
547 if (isdir(config->exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000548 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100549 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000550
Fred Drakeedabdc12000-07-08 06:16:37 +0000551 /* Fail */
552 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000553}
554
Guido van Rossum305e5d01997-04-11 17:18:45 +0000555
Victor Stinner0327bde2017-11-23 17:03:20 +0100556static void
557calculate_exec_prefix(PyCalculatePath *calculate, PyPathConfig *config)
558{
559 calculate->exec_prefix_found = search_for_exec_prefix(calculate, config);
560 if (!calculate->exec_prefix_found) {
561 if (!Py_FrozenFlag) {
562 fprintf(stderr,
563 "Could not find platform dependent libraries <exec_prefix>\n");
564 }
565 wcsncpy(config->exec_prefix, calculate->exec_prefix, MAXPATHLEN);
566 joinpath(config->exec_prefix, L"lib/lib-dynload");
567 }
568 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
569}
570
571
572static void
573calculate_reduce_exec_prefix(PyCalculatePath *calculate, PyPathConfig *config)
574{
575 if (calculate->exec_prefix_found > 0) {
576 reduce(config->exec_prefix);
577 reduce(config->exec_prefix);
578 reduce(config->exec_prefix);
579 if (!config->exec_prefix[0]) {
580 wcscpy(config->exec_prefix, separator);
581 }
582 }
583 else {
584 wcsncpy(config->exec_prefix, calculate->exec_prefix, MAXPATHLEN);
585 }
586}
587
588
589static void
590calculate_progpath(PyCalculatePath *calculate, PyPathConfig *config)
591{
Victor Stinnerb9197952017-11-23 19:02:04 +0100592#ifdef __APPLE__
593#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
594 uint32_t nsexeclength = MAXPATHLEN;
595#else
596 unsigned long nsexeclength = MAXPATHLEN;
597#endif
598 char execpath[MAXPATHLEN+1];
599#endif
600
Victor Stinner0327bde2017-11-23 17:03:20 +0100601 /* If there is no slash in the argv0 path, then we have to
602 * assume python is on the user's $PATH, since there's no
603 * other way to find a directory to start the search from. If
604 * $PATH isn't exported, you lose.
605 */
606 if (wcschr(calculate->prog, SEP)) {
607 wcsncpy(config->progpath, calculate->prog, MAXPATHLEN);
608 }
Jack Jansen1afd4802004-06-03 14:33:03 +0000609#ifdef __APPLE__
Jack Jansen1afd4802004-06-03 14:33:03 +0000610 /* On Mac OS X, if a script uses an interpreter of the form
611 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
612 * as argv[0], which falls through to the $PATH search below.
613 * If /opt/python2.3/bin isn't in your path, or is near the end,
614 * this algorithm may incorrectly find /usr/bin/python. To work
615 * around this, we can use _NSGetExecutablePath to get a better
616 * hint of what the intended interpreter was, although this
617 * will fail if a relative path was used. but in that case,
618 * absolutize() should help us out below
619 */
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000620 else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100621 size_t r = mbstowcs(config->progpath, execpath, MAXPATHLEN+1);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000622 if (r == (size_t)-1 || r > MAXPATHLEN) {
623 /* Could not convert execpath, or it's too long. */
Victor Stinner0327bde2017-11-23 17:03:20 +0100624 config->progpath[0] = '\0';
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000626 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000627#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100628 else if (calculate->path_env) {
629 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000630 while (1) {
631 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000632
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000633 if (delim) {
634 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100635 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000636 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100637 }
638 wcsncpy(config->progpath, path, len);
639 *(config->progpath + len) = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000640 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100641 else {
642 wcsncpy(config->progpath, path, MAXPATHLEN);
643 }
Jack Jansen55070f52001-12-02 23:56:28 +0000644
Victor Stinner0327bde2017-11-23 17:03:20 +0100645 joinpath(config->progpath, calculate->prog);
646 if (isxfile(config->progpath)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000647 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100648 }
Jack Jansen55070f52001-12-02 23:56:28 +0000649
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000650 if (!delim) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100651 config->progpath[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000652 break;
653 }
654 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000656 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100657 else {
658 config->progpath[0] = '\0';
659 }
660 if (config->progpath[0] != SEP && config->progpath[0] != '\0') {
661 absolutize(config->progpath);
662 }
663}
664
665
666static void
667calculate_argv0_path(PyCalculatePath *calculate, PyPathConfig *config)
668{
669 wcsncpy(calculate->argv0_path, config->progpath, MAXPATHLEN);
670 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000671
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000672#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100673 NSModule pythonModule;
674
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000675 /* On Mac OS X we have a special case if we're running from a framework.
676 ** This is because the python home should be set relative to the library,
677 ** which is in the framework, not relative to the executable, which may
678 ** be outside of the framework. Except when we're in the build directory...
679 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000680 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
681 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100682 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100683 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000684 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000685 /* See if we might be in the build directory. The framework in the
686 ** build directory is incomplete, it only has the .dylib and a few
687 ** needed symlinks, it doesn't have the Lib directories and such.
688 ** If we're running with the framework from the build directory we must
689 ** be running the interpreter in the build directory, so we use the
690 ** build-directory-specific logic to find Lib and such.
691 */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200692 wchar_t* wbuf = Py_DecodeLocale(modPath, NULL);
Vinay Sajip90db6612012-07-17 17:33:46 +0100693 if (wbuf == NULL) {
694 Py_FatalError("Cannot decode framework location");
695 }
696
Victor Stinner0327bde2017-11-23 17:03:20 +0100697 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
698 reduce(calculate->argv0_path);
699 joinpath(calculate->argv0_path, calculate->lib_python);
700 joinpath(calculate->argv0_path, LANDMARK);
701 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000702 /* We are in the build directory so use the name of the
703 executable - we know that the absolute path is passed */
Victor Stinner0327bde2017-11-23 17:03:20 +0100704 wcsncpy(calculate->argv0_path, config->progpath, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000705 }
706 else {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000707 /* Use the location of the library as the progpath */
Victor Stinner0327bde2017-11-23 17:03:20 +0100708 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000709 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200710 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000711 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000712#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000713
Guido van Rossum305e5d01997-04-11 17:18:45 +0000714#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100715 wchar_t tmpbuffer[MAXPATHLEN+1];
716 int linklen = _Py_wreadlink(config->progpath, tmpbuffer, MAXPATHLEN);
717 while (linklen != -1) {
718 if (tmpbuffer[0] == SEP) {
719 /* tmpbuffer should never be longer than MAXPATHLEN,
720 but extra check does not hurt */
721 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000722 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100723 else {
724 /* Interpret relative to progpath */
725 reduce(calculate->argv0_path);
726 joinpath(calculate->argv0_path, tmpbuffer);
727 }
728 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000729 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000730#endif /* HAVE_READLINK */
731
Victor Stinner0327bde2017-11-23 17:03:20 +0100732 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000733 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100734 MAXPATHLEN bytes long. */
735}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000736
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100737
Victor Stinner0327bde2017-11-23 17:03:20 +0100738/* Search for an "pyvenv.cfg" environment configuration file, first in the
739 executable's directory and then in the parent directory.
740 If found, open it for use when searching for prefixes.
741*/
742static void
743calculate_read_pyenv(PyCalculatePath *calculate)
744{
745 wchar_t tmpbuffer[MAXPATHLEN+1];
746 wchar_t *env_cfg = L"pyvenv.cfg";
747 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100748
Victor Stinner0327bde2017-11-23 17:03:20 +0100749 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100750
Victor Stinner0327bde2017-11-23 17:03:20 +0100751 joinpath(tmpbuffer, env_cfg);
752 env_file = _Py_wfopen(tmpbuffer, L"r");
753 if (env_file == NULL) {
754 errno = 0;
755
756 reduce(tmpbuffer);
757 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100758 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100759
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100760 env_file = _Py_wfopen(tmpbuffer, L"r");
761 if (env_file == NULL) {
762 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100763 }
764 }
765
Victor Stinner0327bde2017-11-23 17:03:20 +0100766 if (env_file == NULL) {
767 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000768 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000769
Victor Stinner0327bde2017-11-23 17:03:20 +0100770 /* Look for a 'home' variable and set argv0_path to it, if found */
771 if (find_env_config_value(env_file, L"home", tmpbuffer)) {
772 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000773 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100774 fclose(env_file);
775}
Just van Rossum52e14d62002-12-30 22:08:05 +0000776
Guido van Rossum305e5d01997-04-11 17:18:45 +0000777
Victor Stinner0327bde2017-11-23 17:03:20 +0100778static void
779calculate_zip_path(PyCalculatePath *calculate, PyPathConfig *config)
780{
781 wcsncpy(calculate->zip_path, config->prefix, MAXPATHLEN);
782 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000783
Victor Stinner0327bde2017-11-23 17:03:20 +0100784 if (calculate->prefix_found > 0) {
785 /* Use the reduced prefix returned by Py_GetPrefix() */
786 reduce(calculate->zip_path);
787 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100788 }
789 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100790 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
791 }
792 joinpath(calculate->zip_path, L"lib/python00.zip");
793
794 /* Replace "00" with version */
795 size_t bufsz = wcslen(calculate->zip_path);
796 calculate->zip_path[bufsz - 6] = VERSION[0];
797 calculate->zip_path[bufsz - 5] = VERSION[2];
798}
799
800
801static wchar_t *
802calculate_module_search_path(PyCalculatePath *calculate, PyPathConfig *config)
803{
804 /* Calculate size of return buffer */
805 size_t bufsz = 0;
806 if (calculate->module_search_path_env != NULL) {
807 bufsz += wcslen(calculate->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000808 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000809
Victor Stinner0327bde2017-11-23 17:03:20 +0100810 wchar_t *defpath = calculate->pythonpath;
811 size_t prefixsz = wcslen(config->prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000812 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000813 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000814
Victor Stinner0327bde2017-11-23 17:03:20 +0100815 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000816 /* Paths are relative to prefix */
817 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100818 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000819
Victor Stinner0327bde2017-11-23 17:03:20 +0100820 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000821 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100822 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000823 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000824 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000825 break;
826 }
827 defpath = delim + 1;
828 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000829
Victor Stinner0327bde2017-11-23 17:03:20 +0100830 bufsz += wcslen(calculate->zip_path) + 1;
831 bufsz += wcslen(config->exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000832
Victor Stinner0327bde2017-11-23 17:03:20 +0100833 /* Allocate the buffer */
834 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000835 if (buf == NULL) {
Victor Stinner72967a42013-11-16 01:22:04 +0100836 Py_FatalError(
837 "Not enough memory for dynamic PYTHONPATH");
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 Stinner0327bde2017-11-23 17:03:20 +0100842 if (calculate->module_search_path_env) {
843 wcscpy(buf, calculate->module_search_path_env);
844 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 Stinner0327bde2017-11-23 17:03:20 +0100859 wcscat(buf, config->prefix);
860 if (prefixsz >= 2 && config->prefix[prefixsz - 2] != SEP &&
861 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);
872 *(buf + end) = '\0';
873 }
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 Stinner0327bde2017-11-23 17:03:20 +0100883 wcscat(buf, config->exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100884
Victor Stinner0327bde2017-11-23 17:03:20 +0100885 return buf;
886}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000887
Victor Stinner0327bde2017-11-23 17:03:20 +0100888
889#define DECODE_FAILED(NAME, LEN) \
890 ((LEN) == (size_t)-2) \
891 ? _Py_INIT_ERR("failed to decode " #NAME) \
892 : _Py_INIT_NO_MEMORY()
893
894
895static _PyInitError
896calculate_init(PyCalculatePath *calculate,
897 const _PyMainInterpreterConfig *main_config)
898{
899 _PyInitError err;
900
901 err = _Py_GetPythonHomeWithConfig(main_config, &calculate->home);
902 if (_Py_INIT_FAILED(err)) {
903 return err;
Fred Drakeedabdc12000-07-08 06:16:37 +0000904 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000905
Victor Stinner0327bde2017-11-23 17:03:20 +0100906 size_t len;
907 char *path = getenv("PATH");
908 if (path) {
909 calculate->path_env = Py_DecodeLocale(path, &len);
910 if (!calculate->path_env) {
911 return DECODE_FAILED("PATH environment variable", len);
912 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000913 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000914
Victor Stinner0327bde2017-11-23 17:03:20 +0100915 calculate->prog = Py_GetProgramName();
916
917 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
918 if (!calculate->pythonpath) {
919 return DECODE_FAILED("PYTHONPATH define", len);
920 }
921 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
922 if (!calculate->prefix) {
923 return DECODE_FAILED("PREFIX define", len);
924 }
925 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
926 if (!calculate->prefix) {
927 return DECODE_FAILED("EXEC_PREFIX define", len);
928 }
929 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
930 if (!calculate->lib_python) {
931 return DECODE_FAILED("EXEC_PREFIX define", len);
932 }
933
934 calculate->module_search_path_env = NULL;
935 if (main_config) {
936 if (main_config->module_search_path_env) {
937 calculate->module_search_path_env = main_config->module_search_path_env;
938 }
939
940 }
941 else {
942 char *pythonpath = Py_GETENV("PYTHONPATH");
943 if (pythonpath && pythonpath[0] != '\0') {
944 calculate->module_search_path_buffer = Py_DecodeLocale(pythonpath, &len);
945 if (!calculate->module_search_path_buffer) {
946 return DECODE_FAILED("PYTHONPATH environment variable", len);
947 }
948 calculate->module_search_path_env = calculate->module_search_path_buffer;
949 }
950 }
951 return _Py_INIT_OK();
952}
953
954
955static void
956calculate_free(PyCalculatePath *calculate)
957{
958 PyMem_RawFree(calculate->pythonpath);
959 PyMem_RawFree(calculate->prefix);
960 PyMem_RawFree(calculate->exec_prefix);
961 PyMem_RawFree(calculate->lib_python);
962 PyMem_RawFree(calculate->path_env);
963 PyMem_RawFree(calculate->module_search_path_buffer);
964}
965
966
967static void
968calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config)
969{
970 calculate_progpath(calculate, config);
971 calculate_argv0_path(calculate, config);
972 calculate_read_pyenv(calculate);
973 calculate_prefix(calculate, config);
974 calculate_zip_path(calculate, config);
975 calculate_exec_prefix(calculate, config);
976
977 if ((!calculate->prefix_found || !calculate->exec_prefix_found) && !Py_FrozenFlag) {
978 fprintf(stderr,
979 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
980 }
981
982 config->module_search_path = calculate_module_search_path(calculate, config);
983 calculate_reduce_prefix(calculate, config);
984 calculate_reduce_exec_prefix(calculate, config);
985}
986
987
988static void
989calculate_path(const _PyMainInterpreterConfig *main_config)
990{
991 PyCalculatePath calculate;
992 memset(&calculate, 0, sizeof(calculate));
993
994 _PyInitError err = calculate_init(&calculate, main_config);
995 if (_Py_INIT_FAILED(err)) {
996 calculate_free(&calculate);
997 _Py_FatalInitError(err);
998 }
999
1000 PyPathConfig new_path_config;
1001 memset(&new_path_config, 0, sizeof(new_path_config));
1002
1003 calculate_path_impl(&calculate, &new_path_config);
1004 path_config = new_path_config;
1005
1006 calculate_free(&calculate);
Guido van Rossum305e5d01997-04-11 17:18:45 +00001007}
1008
1009
1010/* External interface */
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +00001011void
1012Py_SetPath(const wchar_t *path)
1013{
Victor Stinner0327bde2017-11-23 17:03:20 +01001014 if (path_config.module_search_path != NULL) {
1015 PyMem_RawFree(path_config.module_search_path);
1016 path_config.module_search_path = NULL;
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +00001017 }
Victor Stinner0327bde2017-11-23 17:03:20 +01001018
1019 if (path == NULL) {
1020 return;
1021 }
1022
1023 wchar_t *prog = Py_GetProgramName();
1024 wcsncpy(path_config.progpath, prog, MAXPATHLEN);
1025 path_config.exec_prefix[0] = path_config.prefix[0] = L'\0';
1026 path_config.module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
1027 if (path_config.module_search_path != NULL) {
1028 wcscpy(path_config.module_search_path, path);
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +00001029 }
1030}
Guido van Rossum667d7041995-08-04 04:20:48 +00001031
Victor Stinner0327bde2017-11-23 17:03:20 +01001032
Martin v. Löwis790465f2008-04-05 20:41:37 +00001033wchar_t *
Victor Stinner0327bde2017-11-23 17:03:20 +01001034_Py_GetPathWithConfig(const _PyMainInterpreterConfig *main_config)
Victor Stinnerd4341102017-11-23 00:12:09 +01001035{
Victor Stinner0327bde2017-11-23 17:03:20 +01001036 if (!path_config.module_search_path) {
1037 calculate_path(main_config);
Victor Stinnerd4341102017-11-23 00:12:09 +01001038 }
Victor Stinner0327bde2017-11-23 17:03:20 +01001039 return path_config.module_search_path;
Victor Stinnerd4341102017-11-23 00:12:09 +01001040}
1041
Victor Stinner0327bde2017-11-23 17:03:20 +01001042
Victor Stinnerd4341102017-11-23 00:12:09 +01001043wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001044Py_GetPath(void)
Guido van Rossum667d7041995-08-04 04:20:48 +00001045{
Victor Stinner0327bde2017-11-23 17:03:20 +01001046 if (!path_config.module_search_path) {
Victor Stinnerd4341102017-11-23 00:12:09 +01001047 calculate_path(NULL);
Victor Stinner0327bde2017-11-23 17:03:20 +01001048 }
1049 return path_config.module_search_path;
Guido van Rossum667d7041995-08-04 04:20:48 +00001050}
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001051
Victor Stinner0327bde2017-11-23 17:03:20 +01001052
Martin v. Löwis790465f2008-04-05 20:41:37 +00001053wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001054Py_GetPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001055{
Victor Stinner0327bde2017-11-23 17:03:20 +01001056 if (!path_config.module_search_path) {
Victor Stinnerd4341102017-11-23 00:12:09 +01001057 calculate_path(NULL);
Victor Stinner0327bde2017-11-23 17:03:20 +01001058 }
1059 return path_config.prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001060}
1061
Victor Stinner0327bde2017-11-23 17:03:20 +01001062
Martin v. Löwis790465f2008-04-05 20:41:37 +00001063wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001064Py_GetExecPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001065{
Victor Stinner0327bde2017-11-23 17:03:20 +01001066 if (!path_config.module_search_path) {
Victor Stinnerd4341102017-11-23 00:12:09 +01001067 calculate_path(NULL);
Victor Stinner0327bde2017-11-23 17:03:20 +01001068 }
1069 return path_config.exec_prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001070}
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001071
Victor Stinner0327bde2017-11-23 17:03:20 +01001072
Martin v. Löwis790465f2008-04-05 20:41:37 +00001073wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001074Py_GetProgramFullPath(void)
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001075{
Victor Stinner0327bde2017-11-23 17:03:20 +01001076 if (!path_config.module_search_path) {
Victor Stinnerd4341102017-11-23 00:12:09 +01001077 calculate_path(NULL);
Victor Stinner0327bde2017-11-23 17:03:20 +01001078 }
1079 return path_config.progpath;
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001080}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001081
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001082#ifdef __cplusplus
1083}
1084#endif