blob: 235badab230bd162e85b5340dfa998adef27c615 [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) \
115 ? _Py_INIT_USER_ERR("cannot decode " #NAME) \
116 : _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 Stinnerb64de462017-12-01 18:27:09 +0100135static _PyPathConfig _Py_path_config = _PyPathConfig_INIT;
Victor Stinner0327bde2017-11-23 17:03:20 +0100136
Martin v. Löwis790465f2008-04-05 20:41:37 +0000137
Victor Stinner91afbb62015-03-24 12:16:28 +0100138/* Get file status. Encode the path to the locale encoding. */
Victor Stinner91afbb62015-03-24 12:16:28 +0100139static int
140_Py_wstat(const wchar_t* path, struct stat *buf)
141{
142 int err;
143 char *fname;
144 fname = Py_EncodeLocale(path, NULL);
145 if (fname == NULL) {
146 errno = EINVAL;
147 return -1;
148 }
149 err = stat(fname, buf);
150 PyMem_Free(fname);
151 return err;
152}
153
Victor Stinner0327bde2017-11-23 17:03:20 +0100154
Guido van Rossum305e5d01997-04-11 17:18:45 +0000155static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000156reduce(wchar_t *dir)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000157{
Martin v. Löwis790465f2008-04-05 20:41:37 +0000158 size_t i = wcslen(dir);
Fred Drakeedabdc12000-07-08 06:16:37 +0000159 while (i > 0 && dir[i] != SEP)
160 --i;
161 dir[i] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000162}
Guido van Rossumd29806c1998-01-19 22:06:22 +0000163
Victor Stinner0327bde2017-11-23 17:03:20 +0100164
Guido van Rossum305e5d01997-04-11 17:18:45 +0000165static int
Martin v. Löwis790465f2008-04-05 20:41:37 +0000166isfile(wchar_t *filename) /* Is file, not directory */
Guido van Rossum305e5d01997-04-11 17:18:45 +0000167{
Fred Drakeedabdc12000-07-08 06:16:37 +0000168 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100169 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000170 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100171 }
172 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000173 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100174 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000175 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000176}
177
178
179static int
Brett Cannonf299abd2015-04-13 14:21:02 -0400180ismodule(wchar_t *filename) /* Is module -- check for .pyc too */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000181{
Victor Stinner0327bde2017-11-23 17:03:20 +0100182 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000183 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100184 }
Guido van Rossumd29806c1998-01-19 22:06:22 +0000185
Fred Drakeedabdc12000-07-08 06:16:37 +0000186 /* Check for the compiled version of prefix. */
Martin v. Löwis790465f2008-04-05 20:41:37 +0000187 if (wcslen(filename) < MAXPATHLEN) {
Brett Cannonf299abd2015-04-13 14:21:02 -0400188 wcscat(filename, L"c");
Victor Stinner0327bde2017-11-23 17:03:20 +0100189 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000190 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100191 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000192 }
193 return 0;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000194}
195
196
Victor Stinner0327bde2017-11-23 17:03:20 +0100197/* Is executable file */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000198static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100199isxfile(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000200{
Fred Drakeedabdc12000-07-08 06:16:37 +0000201 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100202 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000203 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100204 }
205 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000206 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100207 }
208 if ((buf.st_mode & 0111) == 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000209 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100210 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000211 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000212}
213
214
Victor Stinner0327bde2017-11-23 17:03:20 +0100215/* Is directory */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000216static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100217isdir(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000218{
Fred Drakeedabdc12000-07-08 06:16:37 +0000219 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100220 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000221 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100222 }
223 if (!S_ISDIR(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000224 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100225 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000226 return 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000227}
228
229
Tim Petersec8c5a92004-08-08 01:00:47 +0000230/* Add a path component, by appending stuff to buffer.
231 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
232 NUL-terminated string with no more than MAXPATHLEN characters (not counting
233 the trailing NUL). It's a fatal error if it contains a string longer than
234 that (callers must be careful!). If these requirements are met, it's
235 guaranteed that buffer will still be a NUL-terminated string with no more
236 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
237 stuff as fits will be appended.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000238*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000239static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000240joinpath(wchar_t *buffer, wchar_t *stuff)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000241{
Fred Drakeedabdc12000-07-08 06:16:37 +0000242 size_t n, k;
Victor Stinner0327bde2017-11-23 17:03:20 +0100243 if (stuff[0] == SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000244 n = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100245 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000246 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000247 n = wcslen(buffer);
Victor Stinner0327bde2017-11-23 17:03:20 +0100248 if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000249 buffer[n++] = SEP;
Victor Stinner0327bde2017-11-23 17:03:20 +0100250 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000251 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100252 if (n > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 Py_FatalError("buffer overflow in getpath.c's joinpath()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100254 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000255 k = wcslen(stuff);
Victor Stinner0327bde2017-11-23 17:03:20 +0100256 if (n + k > MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000257 k = MAXPATHLEN - n;
Victor Stinner0327bde2017-11-23 17:03:20 +0100258 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000259 wcsncpy(buffer+n, stuff, k);
Fred Drakeedabdc12000-07-08 06:16:37 +0000260 buffer[n+k] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000261}
262
Victor Stinner0327bde2017-11-23 17:03:20 +0100263
Guido van Rossume296ced2001-09-28 20:00:29 +0000264/* copy_absolute requires that path be allocated at least
265 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000266static void
Victor Stinnerf4061da2010-10-14 12:37:19 +0000267copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000268{
Victor Stinner0327bde2017-11-23 17:03:20 +0100269 if (p[0] == SEP) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000270 wcscpy(path, p);
Victor Stinner0327bde2017-11-23 17:03:20 +0100271 }
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000272 else {
Victor Stinnerf4061da2010-10-14 12:37:19 +0000273 if (!_Py_wgetcwd(path, pathlen)) {
Victor Stinner4f3abb02010-10-07 23:29:18 +0000274 /* unable to get the current directory */
275 wcscpy(path, p);
276 return;
277 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100278 if (p[0] == '.' && p[1] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000279 p += 2;
Victor Stinner0327bde2017-11-23 17:03:20 +0100280 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000281 joinpath(path, p);
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000282 }
283}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000284
Victor Stinner0327bde2017-11-23 17:03:20 +0100285
Guido van Rossume296ced2001-09-28 20:00:29 +0000286/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
287static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000288absolutize(wchar_t *path)
Guido van Rossume296ced2001-09-28 20:00:29 +0000289{
Victor Stinnerf4061da2010-10-14 12:37:19 +0000290 wchar_t buffer[MAXPATHLEN+1];
Guido van Rossume296ced2001-09-28 20:00:29 +0000291
Victor Stinner0327bde2017-11-23 17:03:20 +0100292 if (path[0] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000293 return;
Victor Stinner0327bde2017-11-23 17:03:20 +0100294 }
Victor Stinnerf4061da2010-10-14 12:37:19 +0000295 copy_absolute(buffer, path, MAXPATHLEN+1);
Martin v. Löwis790465f2008-04-05 20:41:37 +0000296 wcscpy(path, buffer);
Guido van Rossume296ced2001-09-28 20:00:29 +0000297}
298
Victor Stinner0327bde2017-11-23 17:03:20 +0100299
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100300/* search for a prefix value in an environment file. If found, copy it
301 to the provided buffer, which is expected to be no more than MAXPATHLEN
302 bytes long.
303*/
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100304static int
305find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
306{
307 int result = 0; /* meaning not found */
308 char buffer[MAXPATHLEN*2+1]; /* allow extra for key, '=', etc. */
309
310 fseek(env_file, 0, SEEK_SET);
311 while (!feof(env_file)) {
312 char * p = fgets(buffer, MAXPATHLEN*2, env_file);
313 wchar_t tmpbuffer[MAXPATHLEN*2+1];
314 PyObject * decoded;
315 int n;
316
Victor Stinner0327bde2017-11-23 17:03:20 +0100317 if (p == NULL) {
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100318 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100319 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100320 n = strlen(p);
321 if (p[n - 1] != '\n') {
322 /* line has overflowed - bail */
323 break;
324 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100325 if (p[0] == '#') {
326 /* Comment - skip */
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100327 continue;
Victor Stinner0327bde2017-11-23 17:03:20 +0100328 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100329 decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
330 if (decoded != NULL) {
331 Py_ssize_t k;
332 wchar_t * state;
333 k = PyUnicode_AsWideChar(decoded,
334 tmpbuffer, MAXPATHLEN * 2);
335 Py_DECREF(decoded);
336 if (k >= 0) {
337 wchar_t * tok = wcstok(tmpbuffer, L" \t\r\n", &state);
338 if ((tok != NULL) && !wcscmp(tok, key)) {
339 tok = wcstok(NULL, L" \t", &state);
340 if ((tok != NULL) && !wcscmp(tok, L"=")) {
341 tok = wcstok(NULL, L"\r\n", &state);
342 if (tok != NULL) {
343 wcsncpy(value, tok, MAXPATHLEN);
344 result = 1;
345 break;
346 }
347 }
348 }
349 }
350 }
351 }
352 return result;
353}
354
Victor Stinner0327bde2017-11-23 17:03:20 +0100355
Guido van Rossume296ced2001-09-28 20:00:29 +0000356/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000357 bytes long.
358*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000359static int
Victor Stinner9ac3d882017-12-01 19:30:41 +0100360search_for_prefix(const _PyMainInterpreterConfig *main_config,
361 PyCalculatePath *calculate, wchar_t *prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000362{
Fred Drakeedabdc12000-07-08 06:16:37 +0000363 size_t n;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000364 wchar_t *vpath;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000365
Fred Drakeedabdc12000-07-08 06:16:37 +0000366 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinner9ac3d882017-12-01 19:30:41 +0100367 if (main_config->home) {
368 wcsncpy(prefix, main_config->home, MAXPATHLEN);
Victor Stinner9316ee42017-11-25 03:17:57 +0100369 prefix[MAXPATHLEN] = L'\0';
370 wchar_t *delim = wcschr(prefix, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100371 if (delim) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000372 *delim = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100373 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100374 joinpath(prefix, calculate->lib_python);
375 joinpath(prefix, LANDMARK);
Fred Drakeedabdc12000-07-08 06:16:37 +0000376 return 1;
377 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000378
Fred Drakeedabdc12000-07-08 06:16:37 +0000379 /* Check to see if argv[0] is in the build directory */
Victor Stinner9316ee42017-11-25 03:17:57 +0100380 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
381 prefix[MAXPATHLEN] = L'\0';
382 joinpath(prefix, L"Modules/Setup");
383 if (isfile(prefix)) {
Neil Schemenauer6cf07022001-01-24 17:13:11 +0000384 /* Check VPATH to see if argv0_path is in the build directory. */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200385 vpath = Py_DecodeLocale(VPATH, NULL);
Victor Stinner21582312010-10-23 00:13:28 +0000386 if (vpath != NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100387 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
388 prefix[MAXPATHLEN] = L'\0';
389 joinpath(prefix, vpath);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200390 PyMem_RawFree(vpath);
Victor Stinner9316ee42017-11-25 03:17:57 +0100391 joinpath(prefix, L"Lib");
392 joinpath(prefix, LANDMARK);
393 if (ismodule(prefix)) {
Victor Stinner21582312010-10-23 00:13:28 +0000394 return -1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100395 }
Victor Stinner21582312010-10-23 00:13:28 +0000396 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000397 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000398
Fred Drakeedabdc12000-07-08 06:16:37 +0000399 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100400 copy_absolute(prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000401 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100402 n = wcslen(prefix);
403 joinpath(prefix, calculate->lib_python);
404 joinpath(prefix, LANDMARK);
405 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000406 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100407 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100408 prefix[n] = L'\0';
409 reduce(prefix);
410 } while (prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000411
Fred Drakeedabdc12000-07-08 06:16:37 +0000412 /* Look at configure's PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100413 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
414 prefix[MAXPATHLEN] = L'\0';
415 joinpath(prefix, calculate->lib_python);
416 joinpath(prefix, LANDMARK);
417 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000418 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100419 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000420
Fred Drakeedabdc12000-07-08 06:16:37 +0000421 /* Fail */
422 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000423}
424
425
Victor Stinner0327bde2017-11-23 17:03:20 +0100426static void
Victor Stinner9ac3d882017-12-01 19:30:41 +0100427calculate_prefix(const _PyMainInterpreterConfig *main_config,
428 PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100429{
Victor Stinner9ac3d882017-12-01 19:30:41 +0100430 calculate->prefix_found = search_for_prefix(main_config, calculate, prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100431 if (!calculate->prefix_found) {
432 if (!Py_FrozenFlag) {
433 fprintf(stderr,
434 "Could not find platform independent libraries <prefix>\n");
435 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100436 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
437 joinpath(prefix, calculate->lib_python);
Victor Stinner0327bde2017-11-23 17:03:20 +0100438 }
439 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100440 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100441 }
442}
443
444
445static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100446calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100447{
448 /* Reduce prefix and exec_prefix to their essence,
449 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
450 * If we're loading relative to the build directory,
451 * return the compiled-in defaults instead.
452 */
453 if (calculate->prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100454 reduce(prefix);
455 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100456 /* The prefix is the root directory, but reduce() chopped
457 * off the "/". */
Victor Stinner9316ee42017-11-25 03:17:57 +0100458 if (!prefix[0]) {
459 wcscpy(prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100460 }
461 }
462 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100463 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100464 }
465}
466
467
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000468/* search_for_exec_prefix requires that argv0_path be no more than
Guido van Rossume296ced2001-09-28 20:00:29 +0000469 MAXPATHLEN bytes long.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000470*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000471static int
Victor Stinner9ac3d882017-12-01 19:30:41 +0100472search_for_exec_prefix(const _PyMainInterpreterConfig *main_config,
473 PyCalculatePath *calculate, wchar_t *exec_prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000474{
Fred Drakeedabdc12000-07-08 06:16:37 +0000475 size_t n;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000476
Fred Drakeedabdc12000-07-08 06:16:37 +0000477 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinner9ac3d882017-12-01 19:30:41 +0100478 if (main_config->home) {
479 wchar_t *delim = wcschr(main_config->home, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100480 if (delim) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100481 wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100482 }
483 else {
Victor Stinner9ac3d882017-12-01 19:30:41 +0100484 wcsncpy(exec_prefix, main_config->home, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100485 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100486 exec_prefix[MAXPATHLEN] = L'\0';
487 joinpath(exec_prefix, calculate->lib_python);
488 joinpath(exec_prefix, L"lib-dynload");
Fred Drakeedabdc12000-07-08 06:16:37 +0000489 return 1;
490 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000491
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000492 /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
493 is written by setup.py and contains the relative path to the location
494 of shared library modules. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100495 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
496 exec_prefix[MAXPATHLEN] = L'\0';
497 joinpath(exec_prefix, L"pybuilddir.txt");
498 if (isfile(exec_prefix)) {
499 FILE *f = _Py_wfopen(exec_prefix, L"rb");
Victor Stinner0327bde2017-11-23 17:03:20 +0100500 if (f == NULL) {
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000501 errno = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100502 }
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000503 else {
504 char buf[MAXPATHLEN+1];
505 PyObject *decoded;
506 wchar_t rel_builddir_path[MAXPATHLEN+1];
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000507 n = fread(buf, 1, MAXPATHLEN, f);
508 buf[n] = '\0';
509 fclose(f);
510 decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
511 if (decoded != NULL) {
Victor Stinner47f637c2010-11-10 14:12:20 +0000512 Py_ssize_t k;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000513 k = PyUnicode_AsWideChar(decoded,
Victor Stinnere406ef42010-08-14 00:07:14 +0000514 rel_builddir_path, MAXPATHLEN);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000515 Py_DECREF(decoded);
Victor Stinner47f637c2010-11-10 14:12:20 +0000516 if (k >= 0) {
517 rel_builddir_path[k] = L'\0';
Victor Stinner9316ee42017-11-25 03:17:57 +0100518 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
519 exec_prefix[MAXPATHLEN] = L'\0';
520 joinpath(exec_prefix, rel_builddir_path);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000521 return -1;
522 }
523 }
524 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000525 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000526
Fred Drakeedabdc12000-07-08 06:16:37 +0000527 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100528 copy_absolute(exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000529 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100530 n = wcslen(exec_prefix);
531 joinpath(exec_prefix, calculate->lib_python);
532 joinpath(exec_prefix, L"lib-dynload");
533 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000534 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100535 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100536 exec_prefix[n] = L'\0';
537 reduce(exec_prefix);
538 } while (exec_prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000539
Fred Drakeedabdc12000-07-08 06:16:37 +0000540 /* Look at configure's EXEC_PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100541 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
542 exec_prefix[MAXPATHLEN] = L'\0';
543 joinpath(exec_prefix, calculate->lib_python);
544 joinpath(exec_prefix, L"lib-dynload");
545 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000546 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100547 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000548
Fred Drakeedabdc12000-07-08 06:16:37 +0000549 /* Fail */
550 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000551}
552
Guido van Rossum305e5d01997-04-11 17:18:45 +0000553
Victor Stinner0327bde2017-11-23 17:03:20 +0100554static void
Victor Stinner9ac3d882017-12-01 19:30:41 +0100555calculate_exec_prefix(const _PyMainInterpreterConfig *main_config,
556 PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100557{
Victor Stinner9ac3d882017-12-01 19:30:41 +0100558 calculate->exec_prefix_found = search_for_exec_prefix(main_config,
559 calculate,
560 exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100561 if (!calculate->exec_prefix_found) {
562 if (!Py_FrozenFlag) {
563 fprintf(stderr,
564 "Could not find platform dependent libraries <exec_prefix>\n");
565 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100566 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
567 joinpath(exec_prefix, L"lib/lib-dynload");
Victor Stinner0327bde2017-11-23 17:03:20 +0100568 }
569 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
570}
571
572
573static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100574calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100575{
576 if (calculate->exec_prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100577 reduce(exec_prefix);
578 reduce(exec_prefix);
579 reduce(exec_prefix);
580 if (!exec_prefix[0]) {
581 wcscpy(exec_prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100582 }
583 }
584 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100585 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100586 }
587}
588
589
Victor Stinner9316ee42017-11-25 03:17:57 +0100590static _PyInitError
Victor Stinner9ac3d882017-12-01 19:30:41 +0100591calculate_program_full_path(const _PyMainInterpreterConfig *main_config,
592 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100593{
Victor Stinnerb64de462017-12-01 18:27:09 +0100594 wchar_t program_full_path[MAXPATHLEN+1];
595 memset(program_full_path, 0, sizeof(program_full_path));
Victor Stinner9316ee42017-11-25 03:17:57 +0100596
Victor Stinnerb9197952017-11-23 19:02:04 +0100597#ifdef __APPLE__
598#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
599 uint32_t nsexeclength = MAXPATHLEN;
600#else
601 unsigned long nsexeclength = MAXPATHLEN;
602#endif
603 char execpath[MAXPATHLEN+1];
604#endif
605
Victor Stinner0327bde2017-11-23 17:03:20 +0100606 /* If there is no slash in the argv0 path, then we have to
607 * assume python is on the user's $PATH, since there's no
608 * other way to find a directory to start the search from. If
609 * $PATH isn't exported, you lose.
610 */
Victor Stinner9ac3d882017-12-01 19:30:41 +0100611 if (wcschr(main_config->program_name, SEP)) {
612 wcsncpy(program_full_path, main_config->program_name, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100613 }
Jack Jansen1afd4802004-06-03 14:33:03 +0000614#ifdef __APPLE__
Jack Jansen1afd4802004-06-03 14:33:03 +0000615 /* On Mac OS X, if a script uses an interpreter of the form
616 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
617 * as argv[0], which falls through to the $PATH search below.
618 * If /opt/python2.3/bin isn't in your path, or is near the end,
619 * this algorithm may incorrectly find /usr/bin/python. To work
620 * around this, we can use _NSGetExecutablePath to get a better
621 * hint of what the intended interpreter was, although this
622 * will fail if a relative path was used. but in that case,
623 * absolutize() should help us out below
624 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100625 else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
626 execpath[0] == SEP)
627 {
Victor Stinnerebac19d2017-12-01 20:09:52 +0100628 size_t len;
629 wchar_t *path = Py_DecodeLocale(execpath, &len);
630 if (path == NULL) {
631 return DECODE_LOCALE_ERR("executable path", len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 }
Victor Stinnerebac19d2017-12-01 20:09:52 +0100633 wcsncpy(program_full_path, path, MAXPATHLEN);
634 PyMem_RawFree(path);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000635 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000636#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100637 else if (calculate->path_env) {
638 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000639 while (1) {
640 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000641
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000642 if (delim) {
643 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100644 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000645 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100646 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100647 wcsncpy(program_full_path, path, len);
648 program_full_path[len] = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000649 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100650 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100651 wcsncpy(program_full_path, path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100652 }
Jack Jansen55070f52001-12-02 23:56:28 +0000653
Victor Stinner9ac3d882017-12-01 19:30:41 +0100654 joinpath(program_full_path, main_config->program_name);
Victor Stinnerb64de462017-12-01 18:27:09 +0100655 if (isxfile(program_full_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000656 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100657 }
Jack Jansen55070f52001-12-02 23:56:28 +0000658
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000659 if (!delim) {
Victor Stinnerb64de462017-12-01 18:27:09 +0100660 program_full_path[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000661 break;
662 }
663 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000665 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100666 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100667 program_full_path[0] = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100668 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100669 if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
670 absolutize(program_full_path);
Victor Stinner0327bde2017-11-23 17:03:20 +0100671 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100672
Victor Stinnerb64de462017-12-01 18:27:09 +0100673 config->program_full_path = _PyMem_RawWcsdup(program_full_path);
674 if (config->program_full_path == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100675 return _Py_INIT_NO_MEMORY();
676 }
677 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100678}
679
680
Victor Stinner9316ee42017-11-25 03:17:57 +0100681static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100682calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path)
Victor Stinner0327bde2017-11-23 17:03:20 +0100683{
Victor Stinnerb64de462017-12-01 18:27:09 +0100684 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100685 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000686
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000687#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100688 NSModule pythonModule;
689
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000690 /* On Mac OS X we have a special case if we're running from a framework.
691 ** This is because the python home should be set relative to the library,
692 ** which is in the framework, not relative to the executable, which may
693 ** be outside of the framework. Except when we're in the build directory...
694 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000695 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
696 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100697 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100698 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000699 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000700 /* See if we might be in the build directory. The framework in the
701 ** build directory is incomplete, it only has the .dylib and a few
702 ** needed symlinks, it doesn't have the Lib directories and such.
703 ** If we're running with the framework from the build directory we must
704 ** be running the interpreter in the build directory, so we use the
705 ** build-directory-specific logic to find Lib and such.
706 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100707 size_t len;
708 wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100709 if (wbuf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100710 return DECODE_LOCALE_ERR("framework location", len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100711 }
712
Victor Stinner0327bde2017-11-23 17:03:20 +0100713 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
714 reduce(calculate->argv0_path);
715 joinpath(calculate->argv0_path, calculate->lib_python);
716 joinpath(calculate->argv0_path, LANDMARK);
717 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000718 /* We are in the build directory so use the name of the
719 executable - we know that the absolute path is passed */
Victor Stinnerb64de462017-12-01 18:27:09 +0100720 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000721 }
722 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100723 /* Use the location of the library as the program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100724 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000725 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200726 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000727 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000728#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000729
Guido van Rossum305e5d01997-04-11 17:18:45 +0000730#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100731 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinnerb64de462017-12-01 18:27:09 +0100732 int linklen = _Py_wreadlink(program_full_path, tmpbuffer, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100733 while (linklen != -1) {
734 if (tmpbuffer[0] == SEP) {
735 /* tmpbuffer should never be longer than MAXPATHLEN,
736 but extra check does not hurt */
737 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000738 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100739 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100740 /* Interpret relative to program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100741 reduce(calculate->argv0_path);
742 joinpath(calculate->argv0_path, tmpbuffer);
743 }
744 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000745 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000746#endif /* HAVE_READLINK */
747
Victor Stinner0327bde2017-11-23 17:03:20 +0100748 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000749 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100750 MAXPATHLEN bytes long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100751 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100752}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000753
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100754
Victor Stinner0327bde2017-11-23 17:03:20 +0100755/* Search for an "pyvenv.cfg" environment configuration file, first in the
756 executable's directory and then in the parent directory.
757 If found, open it for use when searching for prefixes.
758*/
759static void
760calculate_read_pyenv(PyCalculatePath *calculate)
761{
762 wchar_t tmpbuffer[MAXPATHLEN+1];
763 wchar_t *env_cfg = L"pyvenv.cfg";
764 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100765
Victor Stinner0327bde2017-11-23 17:03:20 +0100766 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100767
Victor Stinner0327bde2017-11-23 17:03:20 +0100768 joinpath(tmpbuffer, env_cfg);
769 env_file = _Py_wfopen(tmpbuffer, L"r");
770 if (env_file == NULL) {
771 errno = 0;
772
773 reduce(tmpbuffer);
774 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100775 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100776
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100777 env_file = _Py_wfopen(tmpbuffer, L"r");
778 if (env_file == NULL) {
779 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100780 }
781 }
782
Victor Stinner0327bde2017-11-23 17:03:20 +0100783 if (env_file == NULL) {
784 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000785 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000786
Victor Stinner0327bde2017-11-23 17:03:20 +0100787 /* Look for a 'home' variable and set argv0_path to it, if found */
788 if (find_env_config_value(env_file, L"home", tmpbuffer)) {
789 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000790 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100791 fclose(env_file);
792}
Just van Rossum52e14d62002-12-30 22:08:05 +0000793
Guido van Rossum305e5d01997-04-11 17:18:45 +0000794
Victor Stinner0327bde2017-11-23 17:03:20 +0100795static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100796calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100797{
Victor Stinner9316ee42017-11-25 03:17:57 +0100798 wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100799 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000800
Victor Stinner0327bde2017-11-23 17:03:20 +0100801 if (calculate->prefix_found > 0) {
802 /* Use the reduced prefix returned by Py_GetPrefix() */
803 reduce(calculate->zip_path);
804 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100805 }
806 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100807 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
808 }
809 joinpath(calculate->zip_path, L"lib/python00.zip");
810
811 /* Replace "00" with version */
812 size_t bufsz = wcslen(calculate->zip_path);
813 calculate->zip_path[bufsz - 6] = VERSION[0];
814 calculate->zip_path[bufsz - 5] = VERSION[2];
815}
816
817
Victor Stinner9316ee42017-11-25 03:17:57 +0100818static _PyInitError
Victor Stinner9ac3d882017-12-01 19:30:41 +0100819calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
820 PyCalculatePath *calculate,
Victor Stinner9316ee42017-11-25 03:17:57 +0100821 const wchar_t *prefix, const wchar_t *exec_prefix,
Victor Stinnerb64de462017-12-01 18:27:09 +0100822 _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100823{
824 /* Calculate size of return buffer */
825 size_t bufsz = 0;
Victor Stinner9ac3d882017-12-01 19:30:41 +0100826 if (main_config->module_search_path_env != NULL) {
827 bufsz += wcslen(main_config->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000828 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000829
Victor Stinner0327bde2017-11-23 17:03:20 +0100830 wchar_t *defpath = calculate->pythonpath;
Victor Stinner9316ee42017-11-25 03:17:57 +0100831 size_t prefixsz = wcslen(prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000832 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000833 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000834
Victor Stinner0327bde2017-11-23 17:03:20 +0100835 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000836 /* Paths are relative to prefix */
837 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100838 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000839
Victor Stinner0327bde2017-11-23 17:03:20 +0100840 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000841 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100842 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000843 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000844 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000845 break;
846 }
847 defpath = delim + 1;
848 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000849
Victor Stinner0327bde2017-11-23 17:03:20 +0100850 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner9316ee42017-11-25 03:17:57 +0100851 bufsz += wcslen(exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000852
Victor Stinner0327bde2017-11-23 17:03:20 +0100853 /* Allocate the buffer */
854 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000855 if (buf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100856 return _Py_INIT_NO_MEMORY();
Fred Drakeedabdc12000-07-08 06:16:37 +0000857 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100858 buf[0] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000859
Victor Stinner72967a42013-11-16 01:22:04 +0100860 /* Run-time value of $PYTHONPATH goes first */
Victor Stinner9ac3d882017-12-01 19:30:41 +0100861 if (main_config->module_search_path_env) {
862 wcscpy(buf, main_config->module_search_path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100863 wcscat(buf, delimiter);
Fred Drakeedabdc12000-07-08 06:16:37 +0000864 }
Victor Stinner72967a42013-11-16 01:22:04 +0100865
866 /* Next is the default zip path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100867 wcscat(buf, calculate->zip_path);
Victor Stinner72967a42013-11-16 01:22:04 +0100868 wcscat(buf, delimiter);
869
870 /* Next goes merge of compile-time $PYTHONPATH with
871 * dynamically located prefix.
872 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100873 defpath = calculate->pythonpath;
Victor Stinner72967a42013-11-16 01:22:04 +0100874 while (1) {
875 wchar_t *delim = wcschr(defpath, DELIM);
876
877 if (defpath[0] != SEP) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100878 wcscat(buf, prefix);
879 if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
Victor Stinner0327bde2017-11-23 17:03:20 +0100880 defpath[0] != (delim ? DELIM : L'\0'))
881 {
882 /* not empty */
Serhiy Storchaka62e32d62016-11-11 12:05:01 +0200883 wcscat(buf, separator);
884 }
Victor Stinner72967a42013-11-16 01:22:04 +0100885 }
886
887 if (delim) {
888 size_t len = delim - defpath + 1;
889 size_t end = wcslen(buf) + len;
890 wcsncat(buf, defpath, len);
Victor Stinner9316ee42017-11-25 03:17:57 +0100891 buf[end] = '\0';
Victor Stinner72967a42013-11-16 01:22:04 +0100892 }
893 else {
894 wcscat(buf, defpath);
895 break;
896 }
897 defpath = delim + 1;
898 }
899 wcscat(buf, delimiter);
900
901 /* Finally, on goes the directory for dynamic-load modules */
Victor Stinner9316ee42017-11-25 03:17:57 +0100902 wcscat(buf, exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100903
Victor Stinner9316ee42017-11-25 03:17:57 +0100904 config->module_search_path = buf;
905 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100906}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000907
Victor Stinner0327bde2017-11-23 17:03:20 +0100908
Victor Stinner0327bde2017-11-23 17:03:20 +0100909static _PyInitError
910calculate_init(PyCalculatePath *calculate,
911 const _PyMainInterpreterConfig *main_config)
912{
Victor Stinner0327bde2017-11-23 17:03:20 +0100913 size_t len;
914 char *path = getenv("PATH");
915 if (path) {
916 calculate->path_env = Py_DecodeLocale(path, &len);
917 if (!calculate->path_env) {
Victor Stinner46972b72017-11-24 22:55:40 +0100918 return DECODE_LOCALE_ERR("PATH environment variable", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100919 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000920 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000921
Victor Stinner0327bde2017-11-23 17:03:20 +0100922 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
923 if (!calculate->pythonpath) {
Victor Stinner46972b72017-11-24 22:55:40 +0100924 return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100925 }
926 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
927 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100928 return DECODE_LOCALE_ERR("PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100929 }
930 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
931 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100932 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100933 }
934 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
935 if (!calculate->lib_python) {
Victor Stinner46972b72017-11-24 22:55:40 +0100936 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100937 }
938 return _Py_INIT_OK();
939}
940
941
942static void
943calculate_free(PyCalculatePath *calculate)
944{
945 PyMem_RawFree(calculate->pythonpath);
946 PyMem_RawFree(calculate->prefix);
947 PyMem_RawFree(calculate->exec_prefix);
948 PyMem_RawFree(calculate->lib_python);
949 PyMem_RawFree(calculate->path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100950}
951
952
Victor Stinner9316ee42017-11-25 03:17:57 +0100953static _PyInitError
Victor Stinner9ac3d882017-12-01 19:30:41 +0100954calculate_path_impl(const _PyMainInterpreterConfig *main_config,
955 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100956{
Victor Stinner9ac3d882017-12-01 19:30:41 +0100957 _PyInitError err;
958
959 err = calculate_program_full_path(main_config, calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100960 if (_Py_INIT_FAILED(err)) {
961 return err;
962 }
963
Victor Stinnerb64de462017-12-01 18:27:09 +0100964 err = calculate_argv0_path(calculate, config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100965 if (_Py_INIT_FAILED(err)) {
966 return err;
967 }
968
Victor Stinner0327bde2017-11-23 17:03:20 +0100969 calculate_read_pyenv(calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100970
971 wchar_t prefix[MAXPATHLEN+1];
972 memset(prefix, 0, sizeof(prefix));
Victor Stinner9ac3d882017-12-01 19:30:41 +0100973 calculate_prefix(main_config, calculate, prefix);
Victor Stinner9316ee42017-11-25 03:17:57 +0100974
975 calculate_zip_path(calculate, prefix);
976
977 wchar_t exec_prefix[MAXPATHLEN+1];
978 memset(exec_prefix, 0, sizeof(exec_prefix));
Victor Stinner9ac3d882017-12-01 19:30:41 +0100979 calculate_exec_prefix(main_config, calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100980
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100981 if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
982 !Py_FrozenFlag)
983 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100984 fprintf(stderr,
985 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
986 }
987
Victor Stinner9ac3d882017-12-01 19:30:41 +0100988 err = calculate_module_search_path(main_config, calculate,
989 prefix, exec_prefix, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100990 if (_Py_INIT_FAILED(err)) {
991 return err;
992 }
993
994 calculate_reduce_prefix(calculate, prefix);
995
996 config->prefix = _PyMem_RawWcsdup(prefix);
997 if (config->prefix == NULL) {
998 return _Py_INIT_NO_MEMORY();
999 }
1000
1001 calculate_reduce_exec_prefix(calculate, exec_prefix);
1002
1003 config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
1004 if (config->exec_prefix == NULL) {
1005 return _Py_INIT_NO_MEMORY();
1006 }
1007
1008 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001009}
1010
1011
1012static void
Victor Stinnerb64de462017-12-01 18:27:09 +01001013pathconfig_clear(_PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +01001014{
Victor Stinner9316ee42017-11-25 03:17:57 +01001015#define CLEAR(ATTR) \
1016 do { \
1017 PyMem_RawFree(ATTR); \
1018 ATTR = NULL; \
1019 } while (0)
1020
1021 CLEAR(config->prefix);
1022 CLEAR(config->exec_prefix);
Victor Stinnerb64de462017-12-01 18:27:09 +01001023 CLEAR(config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +01001024 CLEAR(config->module_search_path);
1025#undef CLEAR
1026}
1027
1028
1029/* Initialize paths for Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix()
1030 and Py_GetProgramFullPath() */
1031_PyInitError
1032_PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
1033{
Victor Stinnerb64de462017-12-01 18:27:09 +01001034 if (_Py_path_config.module_search_path) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001035 /* Already initialized */
1036 return _Py_INIT_OK();
1037 }
1038
Victor Stinner0327bde2017-11-23 17:03:20 +01001039 PyCalculatePath calculate;
1040 memset(&calculate, 0, sizeof(calculate));
1041
Victor Stinner9316ee42017-11-25 03:17:57 +01001042 _PyInitError err = calculate_init(&calculate, main_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001043 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001044 goto done;
Victor Stinner0327bde2017-11-23 17:03:20 +01001045 }
1046
Victor Stinnerb64de462017-12-01 18:27:09 +01001047 _PyPathConfig new_path_config;
Victor Stinner0327bde2017-11-23 17:03:20 +01001048 memset(&new_path_config, 0, sizeof(new_path_config));
1049
Victor Stinner9ac3d882017-12-01 19:30:41 +01001050 err = calculate_path_impl(main_config, &calculate, &new_path_config);
Victor Stinner9316ee42017-11-25 03:17:57 +01001051 if (_Py_INIT_FAILED(err)) {
1052 pathconfig_clear(&new_path_config);
1053 goto done;
1054 }
1055
Victor Stinnerb64de462017-12-01 18:27:09 +01001056 _Py_path_config = new_path_config;
Victor Stinner9316ee42017-11-25 03:17:57 +01001057 err = _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001058
Victor Stinner9316ee42017-11-25 03:17:57 +01001059done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001060 calculate_free(&calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +01001061 return err;
1062}
Victor Stinner46972b72017-11-24 22:55:40 +01001063
Victor Stinner9316ee42017-11-25 03:17:57 +01001064
1065static void
Victor Stinnerb64de462017-12-01 18:27:09 +01001066pathconfig_global_init(void)
Victor Stinner9316ee42017-11-25 03:17:57 +01001067{
Victor Stinnerb64de462017-12-01 18:27:09 +01001068 if (_Py_path_config.module_search_path) {
1069 /* Already initialized */
1070 return;
1071 }
1072
Victor Stinner9316ee42017-11-25 03:17:57 +01001073 _PyInitError err;
1074 _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
1075
1076 err = _PyMainInterpreterConfig_ReadEnv(&config);
Victor Stinner9316ee42017-11-25 03:17:57 +01001077 if (_Py_INIT_FAILED(err)) {
Victor Stinner9ac3d882017-12-01 19:30:41 +01001078 goto error;
Victor Stinner9316ee42017-11-25 03:17:57 +01001079 }
Victor Stinner9ac3d882017-12-01 19:30:41 +01001080
1081 err = _PyMainInterpreterConfig_Read(&config);
1082 if (_Py_INIT_FAILED(err)) {
1083 goto error;
1084 }
1085
1086 err = _PyPathConfig_Init(&config);
1087 if (_Py_INIT_FAILED(err)) {
1088 goto error;
1089 }
1090
1091 _PyMainInterpreterConfig_Clear(&config);
1092 return;
1093
1094error:
1095 _PyMainInterpreterConfig_Clear(&config);
1096 _Py_FatalInitError(err);
Victor Stinner9316ee42017-11-25 03:17:57 +01001097}
1098
1099
1100void
1101_PyPathConfig_Fini(void)
1102{
Victor Stinnerb64de462017-12-01 18:27:09 +01001103 pathconfig_clear(&_Py_path_config);
Guido van Rossum305e5d01997-04-11 17:18:45 +00001104}
1105
1106
1107/* External interface */
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +00001108void
1109Py_SetPath(const wchar_t *path)
1110{
Victor Stinner0327bde2017-11-23 17:03:20 +01001111 if (path == NULL) {
Victor Stinnerb64de462017-12-01 18:27:09 +01001112 pathconfig_clear(&_Py_path_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001113 return;
1114 }
1115
Victor Stinnerb64de462017-12-01 18:27:09 +01001116 _PyPathConfig new_config;
1117 new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
Victor Stinner9316ee42017-11-25 03:17:57 +01001118 new_config.exec_prefix = _PyMem_RawWcsdup(L"");
1119 new_config.prefix = _PyMem_RawWcsdup(L"");
1120 new_config.module_search_path = _PyMem_RawWcsdup(path);
Guido van Rossum667d7041995-08-04 04:20:48 +00001121
Victor Stinnerb64de462017-12-01 18:27:09 +01001122 pathconfig_clear(&_Py_path_config);
1123 _Py_path_config = new_config;
Victor Stinnerd4341102017-11-23 00:12:09 +01001124}
1125
Victor Stinner0327bde2017-11-23 17:03:20 +01001126
Victor Stinnerd4341102017-11-23 00:12:09 +01001127wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001128Py_GetPath(void)
Guido van Rossum667d7041995-08-04 04:20:48 +00001129{
Victor Stinnerb64de462017-12-01 18:27:09 +01001130 pathconfig_global_init();
1131 return _Py_path_config.module_search_path;
Guido van Rossum667d7041995-08-04 04:20:48 +00001132}
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001133
Victor Stinner0327bde2017-11-23 17:03:20 +01001134
Martin v. Löwis790465f2008-04-05 20:41:37 +00001135wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001136Py_GetPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001137{
Victor Stinnerb64de462017-12-01 18:27:09 +01001138 pathconfig_global_init();
1139 return _Py_path_config.prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001140}
1141
Victor Stinner0327bde2017-11-23 17:03:20 +01001142
Martin v. Löwis790465f2008-04-05 20:41:37 +00001143wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001144Py_GetExecPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001145{
Victor Stinnerb64de462017-12-01 18:27:09 +01001146 pathconfig_global_init();
1147 return _Py_path_config.exec_prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001148}
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001149
Victor Stinner0327bde2017-11-23 17:03:20 +01001150
Martin v. Löwis790465f2008-04-05 20:41:37 +00001151wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001152Py_GetProgramFullPath(void)
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001153{
Victor Stinnerb64de462017-12-01 18:27:09 +01001154 pathconfig_global_init();
1155 return _Py_path_config.program_full_path;
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001156}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001157
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001158#ifdef __cplusplus
1159}
1160#endif