blob: 183717d817173ea4aefa8277e41db7c61cbd58d9 [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 Stinnerb64de462017-12-01 18:27:09 +0100628 size_t r = mbstowcs(program_full_path, execpath, MAXPATHLEN+1);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000629 if (r == (size_t)-1 || r > MAXPATHLEN) {
630 /* Could not convert execpath, or it's too long. */
Victor Stinnerb64de462017-12-01 18:27:09 +0100631 program_full_path[0] = '\0';
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000633 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000634#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100635 else if (calculate->path_env) {
636 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000637 while (1) {
638 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000639
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000640 if (delim) {
641 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100642 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000643 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100644 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100645 wcsncpy(program_full_path, path, len);
646 program_full_path[len] = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000647 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100648 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100649 wcsncpy(program_full_path, path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100650 }
Jack Jansen55070f52001-12-02 23:56:28 +0000651
Victor Stinner9ac3d882017-12-01 19:30:41 +0100652 joinpath(program_full_path, main_config->program_name);
Victor Stinnerb64de462017-12-01 18:27:09 +0100653 if (isxfile(program_full_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000654 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100655 }
Jack Jansen55070f52001-12-02 23:56:28 +0000656
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000657 if (!delim) {
Victor Stinnerb64de462017-12-01 18:27:09 +0100658 program_full_path[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000659 break;
660 }
661 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000663 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100664 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100665 program_full_path[0] = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100666 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100667 if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
668 absolutize(program_full_path);
Victor Stinner0327bde2017-11-23 17:03:20 +0100669 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100670
Victor Stinnerb64de462017-12-01 18:27:09 +0100671 config->program_full_path = _PyMem_RawWcsdup(program_full_path);
672 if (config->program_full_path == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100673 return _Py_INIT_NO_MEMORY();
674 }
675 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100676}
677
678
Victor Stinner9316ee42017-11-25 03:17:57 +0100679static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100680calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path)
Victor Stinner0327bde2017-11-23 17:03:20 +0100681{
Victor Stinnerb64de462017-12-01 18:27:09 +0100682 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100683 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000684
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000685#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100686 NSModule pythonModule;
687
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000688 /* On Mac OS X we have a special case if we're running from a framework.
689 ** This is because the python home should be set relative to the library,
690 ** which is in the framework, not relative to the executable, which may
691 ** be outside of the framework. Except when we're in the build directory...
692 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000693 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
694 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100695 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100696 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000697 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000698 /* See if we might be in the build directory. The framework in the
699 ** build directory is incomplete, it only has the .dylib and a few
700 ** needed symlinks, it doesn't have the Lib directories and such.
701 ** If we're running with the framework from the build directory we must
702 ** be running the interpreter in the build directory, so we use the
703 ** build-directory-specific logic to find Lib and such.
704 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100705 size_t len;
706 wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100707 if (wbuf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100708 return DECODE_LOCALE_ERR("framework location", len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100709 }
710
Victor Stinner0327bde2017-11-23 17:03:20 +0100711 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
712 reduce(calculate->argv0_path);
713 joinpath(calculate->argv0_path, calculate->lib_python);
714 joinpath(calculate->argv0_path, LANDMARK);
715 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000716 /* We are in the build directory so use the name of the
717 executable - we know that the absolute path is passed */
Victor Stinnerb64de462017-12-01 18:27:09 +0100718 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000719 }
720 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100721 /* Use the location of the library as the program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100722 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000723 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200724 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000725 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000726#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000727
Guido van Rossum305e5d01997-04-11 17:18:45 +0000728#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100729 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinnerb64de462017-12-01 18:27:09 +0100730 int linklen = _Py_wreadlink(program_full_path, tmpbuffer, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100731 while (linklen != -1) {
732 if (tmpbuffer[0] == SEP) {
733 /* tmpbuffer should never be longer than MAXPATHLEN,
734 but extra check does not hurt */
735 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000736 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100737 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100738 /* Interpret relative to program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100739 reduce(calculate->argv0_path);
740 joinpath(calculate->argv0_path, tmpbuffer);
741 }
742 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000743 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000744#endif /* HAVE_READLINK */
745
Victor Stinner0327bde2017-11-23 17:03:20 +0100746 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000747 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100748 MAXPATHLEN bytes long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100749 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100750}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000751
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100752
Victor Stinner0327bde2017-11-23 17:03:20 +0100753/* Search for an "pyvenv.cfg" environment configuration file, first in the
754 executable's directory and then in the parent directory.
755 If found, open it for use when searching for prefixes.
756*/
757static void
758calculate_read_pyenv(PyCalculatePath *calculate)
759{
760 wchar_t tmpbuffer[MAXPATHLEN+1];
761 wchar_t *env_cfg = L"pyvenv.cfg";
762 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100763
Victor Stinner0327bde2017-11-23 17:03:20 +0100764 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100765
Victor Stinner0327bde2017-11-23 17:03:20 +0100766 joinpath(tmpbuffer, env_cfg);
767 env_file = _Py_wfopen(tmpbuffer, L"r");
768 if (env_file == NULL) {
769 errno = 0;
770
771 reduce(tmpbuffer);
772 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100773 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100774
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100775 env_file = _Py_wfopen(tmpbuffer, L"r");
776 if (env_file == NULL) {
777 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100778 }
779 }
780
Victor Stinner0327bde2017-11-23 17:03:20 +0100781 if (env_file == NULL) {
782 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000783 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000784
Victor Stinner0327bde2017-11-23 17:03:20 +0100785 /* Look for a 'home' variable and set argv0_path to it, if found */
786 if (find_env_config_value(env_file, L"home", tmpbuffer)) {
787 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000788 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100789 fclose(env_file);
790}
Just van Rossum52e14d62002-12-30 22:08:05 +0000791
Guido van Rossum305e5d01997-04-11 17:18:45 +0000792
Victor Stinner0327bde2017-11-23 17:03:20 +0100793static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100794calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100795{
Victor Stinner9316ee42017-11-25 03:17:57 +0100796 wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100797 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000798
Victor Stinner0327bde2017-11-23 17:03:20 +0100799 if (calculate->prefix_found > 0) {
800 /* Use the reduced prefix returned by Py_GetPrefix() */
801 reduce(calculate->zip_path);
802 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100803 }
804 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100805 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
806 }
807 joinpath(calculate->zip_path, L"lib/python00.zip");
808
809 /* Replace "00" with version */
810 size_t bufsz = wcslen(calculate->zip_path);
811 calculate->zip_path[bufsz - 6] = VERSION[0];
812 calculate->zip_path[bufsz - 5] = VERSION[2];
813}
814
815
Victor Stinner9316ee42017-11-25 03:17:57 +0100816static _PyInitError
Victor Stinner9ac3d882017-12-01 19:30:41 +0100817calculate_module_search_path(const _PyMainInterpreterConfig *main_config,
818 PyCalculatePath *calculate,
Victor Stinner9316ee42017-11-25 03:17:57 +0100819 const wchar_t *prefix, const wchar_t *exec_prefix,
Victor Stinnerb64de462017-12-01 18:27:09 +0100820 _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100821{
822 /* Calculate size of return buffer */
823 size_t bufsz = 0;
Victor Stinner9ac3d882017-12-01 19:30:41 +0100824 if (main_config->module_search_path_env != NULL) {
825 bufsz += wcslen(main_config->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000826 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000827
Victor Stinner0327bde2017-11-23 17:03:20 +0100828 wchar_t *defpath = calculate->pythonpath;
Victor Stinner9316ee42017-11-25 03:17:57 +0100829 size_t prefixsz = wcslen(prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000830 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000831 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000832
Victor Stinner0327bde2017-11-23 17:03:20 +0100833 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000834 /* Paths are relative to prefix */
835 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100836 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000837
Victor Stinner0327bde2017-11-23 17:03:20 +0100838 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000839 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100840 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000841 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000842 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000843 break;
844 }
845 defpath = delim + 1;
846 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000847
Victor Stinner0327bde2017-11-23 17:03:20 +0100848 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner9316ee42017-11-25 03:17:57 +0100849 bufsz += wcslen(exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000850
Victor Stinner0327bde2017-11-23 17:03:20 +0100851 /* Allocate the buffer */
852 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000853 if (buf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100854 return _Py_INIT_NO_MEMORY();
Fred Drakeedabdc12000-07-08 06:16:37 +0000855 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100856 buf[0] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000857
Victor Stinner72967a42013-11-16 01:22:04 +0100858 /* Run-time value of $PYTHONPATH goes first */
Victor Stinner9ac3d882017-12-01 19:30:41 +0100859 if (main_config->module_search_path_env) {
860 wcscpy(buf, main_config->module_search_path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100861 wcscat(buf, delimiter);
Fred Drakeedabdc12000-07-08 06:16:37 +0000862 }
Victor Stinner72967a42013-11-16 01:22:04 +0100863
864 /* Next is the default zip path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100865 wcscat(buf, calculate->zip_path);
Victor Stinner72967a42013-11-16 01:22:04 +0100866 wcscat(buf, delimiter);
867
868 /* Next goes merge of compile-time $PYTHONPATH with
869 * dynamically located prefix.
870 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100871 defpath = calculate->pythonpath;
Victor Stinner72967a42013-11-16 01:22:04 +0100872 while (1) {
873 wchar_t *delim = wcschr(defpath, DELIM);
874
875 if (defpath[0] != SEP) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100876 wcscat(buf, prefix);
877 if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
Victor Stinner0327bde2017-11-23 17:03:20 +0100878 defpath[0] != (delim ? DELIM : L'\0'))
879 {
880 /* not empty */
Serhiy Storchaka62e32d62016-11-11 12:05:01 +0200881 wcscat(buf, separator);
882 }
Victor Stinner72967a42013-11-16 01:22:04 +0100883 }
884
885 if (delim) {
886 size_t len = delim - defpath + 1;
887 size_t end = wcslen(buf) + len;
888 wcsncat(buf, defpath, len);
Victor Stinner9316ee42017-11-25 03:17:57 +0100889 buf[end] = '\0';
Victor Stinner72967a42013-11-16 01:22:04 +0100890 }
891 else {
892 wcscat(buf, defpath);
893 break;
894 }
895 defpath = delim + 1;
896 }
897 wcscat(buf, delimiter);
898
899 /* Finally, on goes the directory for dynamic-load modules */
Victor Stinner9316ee42017-11-25 03:17:57 +0100900 wcscat(buf, exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100901
Victor Stinner9316ee42017-11-25 03:17:57 +0100902 config->module_search_path = buf;
903 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100904}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000905
Victor Stinner0327bde2017-11-23 17:03:20 +0100906
Victor Stinner0327bde2017-11-23 17:03:20 +0100907static _PyInitError
908calculate_init(PyCalculatePath *calculate,
909 const _PyMainInterpreterConfig *main_config)
910{
Victor Stinner0327bde2017-11-23 17:03:20 +0100911 size_t len;
912 char *path = getenv("PATH");
913 if (path) {
914 calculate->path_env = Py_DecodeLocale(path, &len);
915 if (!calculate->path_env) {
Victor Stinner46972b72017-11-24 22:55:40 +0100916 return DECODE_LOCALE_ERR("PATH environment variable", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100917 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000918 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000919
Victor Stinner0327bde2017-11-23 17:03:20 +0100920 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
921 if (!calculate->pythonpath) {
Victor Stinner46972b72017-11-24 22:55:40 +0100922 return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100923 }
924 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
925 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100926 return DECODE_LOCALE_ERR("PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100927 }
928 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
929 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100930 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100931 }
932 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
933 if (!calculate->lib_python) {
Victor Stinner46972b72017-11-24 22:55:40 +0100934 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100935 }
936 return _Py_INIT_OK();
937}
938
939
940static void
941calculate_free(PyCalculatePath *calculate)
942{
943 PyMem_RawFree(calculate->pythonpath);
944 PyMem_RawFree(calculate->prefix);
945 PyMem_RawFree(calculate->exec_prefix);
946 PyMem_RawFree(calculate->lib_python);
947 PyMem_RawFree(calculate->path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100948}
949
950
Victor Stinner9316ee42017-11-25 03:17:57 +0100951static _PyInitError
Victor Stinner9ac3d882017-12-01 19:30:41 +0100952calculate_path_impl(const _PyMainInterpreterConfig *main_config,
953 PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100954{
Victor Stinner9ac3d882017-12-01 19:30:41 +0100955 _PyInitError err;
956
957 err = calculate_program_full_path(main_config, calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100958 if (_Py_INIT_FAILED(err)) {
959 return err;
960 }
961
Victor Stinnerb64de462017-12-01 18:27:09 +0100962 err = calculate_argv0_path(calculate, config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100963 if (_Py_INIT_FAILED(err)) {
964 return err;
965 }
966
Victor Stinner0327bde2017-11-23 17:03:20 +0100967 calculate_read_pyenv(calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100968
969 wchar_t prefix[MAXPATHLEN+1];
970 memset(prefix, 0, sizeof(prefix));
Victor Stinner9ac3d882017-12-01 19:30:41 +0100971 calculate_prefix(main_config, calculate, prefix);
Victor Stinner9316ee42017-11-25 03:17:57 +0100972
973 calculate_zip_path(calculate, prefix);
974
975 wchar_t exec_prefix[MAXPATHLEN+1];
976 memset(exec_prefix, 0, sizeof(exec_prefix));
Victor Stinner9ac3d882017-12-01 19:30:41 +0100977 calculate_exec_prefix(main_config, calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100978
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100979 if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
980 !Py_FrozenFlag)
981 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100982 fprintf(stderr,
983 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
984 }
985
Victor Stinner9ac3d882017-12-01 19:30:41 +0100986 err = calculate_module_search_path(main_config, calculate,
987 prefix, exec_prefix, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100988 if (_Py_INIT_FAILED(err)) {
989 return err;
990 }
991
992 calculate_reduce_prefix(calculate, prefix);
993
994 config->prefix = _PyMem_RawWcsdup(prefix);
995 if (config->prefix == NULL) {
996 return _Py_INIT_NO_MEMORY();
997 }
998
999 calculate_reduce_exec_prefix(calculate, exec_prefix);
1000
1001 config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
1002 if (config->exec_prefix == NULL) {
1003 return _Py_INIT_NO_MEMORY();
1004 }
1005
1006 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001007}
1008
1009
1010static void
Victor Stinnerb64de462017-12-01 18:27:09 +01001011pathconfig_clear(_PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +01001012{
Victor Stinner9316ee42017-11-25 03:17:57 +01001013#define CLEAR(ATTR) \
1014 do { \
1015 PyMem_RawFree(ATTR); \
1016 ATTR = NULL; \
1017 } while (0)
1018
1019 CLEAR(config->prefix);
1020 CLEAR(config->exec_prefix);
Victor Stinnerb64de462017-12-01 18:27:09 +01001021 CLEAR(config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +01001022 CLEAR(config->module_search_path);
1023#undef CLEAR
1024}
1025
1026
1027/* Initialize paths for Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix()
1028 and Py_GetProgramFullPath() */
1029_PyInitError
1030_PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
1031{
Victor Stinnerb64de462017-12-01 18:27:09 +01001032 if (_Py_path_config.module_search_path) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001033 /* Already initialized */
1034 return _Py_INIT_OK();
1035 }
1036
Victor Stinner0327bde2017-11-23 17:03:20 +01001037 PyCalculatePath calculate;
1038 memset(&calculate, 0, sizeof(calculate));
1039
Victor Stinner9316ee42017-11-25 03:17:57 +01001040 _PyInitError err = calculate_init(&calculate, main_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001041 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001042 goto done;
Victor Stinner0327bde2017-11-23 17:03:20 +01001043 }
1044
Victor Stinnerb64de462017-12-01 18:27:09 +01001045 _PyPathConfig new_path_config;
Victor Stinner0327bde2017-11-23 17:03:20 +01001046 memset(&new_path_config, 0, sizeof(new_path_config));
1047
Victor Stinner9ac3d882017-12-01 19:30:41 +01001048 err = calculate_path_impl(main_config, &calculate, &new_path_config);
Victor Stinner9316ee42017-11-25 03:17:57 +01001049 if (_Py_INIT_FAILED(err)) {
1050 pathconfig_clear(&new_path_config);
1051 goto done;
1052 }
1053
Victor Stinnerb64de462017-12-01 18:27:09 +01001054 _Py_path_config = new_path_config;
Victor Stinner9316ee42017-11-25 03:17:57 +01001055 err = _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001056
Victor Stinner9316ee42017-11-25 03:17:57 +01001057done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001058 calculate_free(&calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +01001059 return err;
1060}
Victor Stinner46972b72017-11-24 22:55:40 +01001061
Victor Stinner9316ee42017-11-25 03:17:57 +01001062
1063static void
Victor Stinnerb64de462017-12-01 18:27:09 +01001064pathconfig_global_init(void)
Victor Stinner9316ee42017-11-25 03:17:57 +01001065{
Victor Stinnerb64de462017-12-01 18:27:09 +01001066 if (_Py_path_config.module_search_path) {
1067 /* Already initialized */
1068 return;
1069 }
1070
Victor Stinner9316ee42017-11-25 03:17:57 +01001071 _PyInitError err;
1072 _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
1073
1074 err = _PyMainInterpreterConfig_ReadEnv(&config);
Victor Stinner9316ee42017-11-25 03:17:57 +01001075 if (_Py_INIT_FAILED(err)) {
Victor Stinner9ac3d882017-12-01 19:30:41 +01001076 goto error;
Victor Stinner9316ee42017-11-25 03:17:57 +01001077 }
Victor Stinner9ac3d882017-12-01 19:30:41 +01001078
1079 err = _PyMainInterpreterConfig_Read(&config);
1080 if (_Py_INIT_FAILED(err)) {
1081 goto error;
1082 }
1083
1084 err = _PyPathConfig_Init(&config);
1085 if (_Py_INIT_FAILED(err)) {
1086 goto error;
1087 }
1088
1089 _PyMainInterpreterConfig_Clear(&config);
1090 return;
1091
1092error:
1093 _PyMainInterpreterConfig_Clear(&config);
1094 _Py_FatalInitError(err);
Victor Stinner9316ee42017-11-25 03:17:57 +01001095}
1096
1097
1098void
1099_PyPathConfig_Fini(void)
1100{
Victor Stinnerb64de462017-12-01 18:27:09 +01001101 pathconfig_clear(&_Py_path_config);
Guido van Rossum305e5d01997-04-11 17:18:45 +00001102}
1103
1104
1105/* External interface */
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +00001106void
1107Py_SetPath(const wchar_t *path)
1108{
Victor Stinner0327bde2017-11-23 17:03:20 +01001109 if (path == NULL) {
Victor Stinnerb64de462017-12-01 18:27:09 +01001110 pathconfig_clear(&_Py_path_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001111 return;
1112 }
1113
Victor Stinnerb64de462017-12-01 18:27:09 +01001114 _PyPathConfig new_config;
1115 new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
Victor Stinner9316ee42017-11-25 03:17:57 +01001116 new_config.exec_prefix = _PyMem_RawWcsdup(L"");
1117 new_config.prefix = _PyMem_RawWcsdup(L"");
1118 new_config.module_search_path = _PyMem_RawWcsdup(path);
Guido van Rossum667d7041995-08-04 04:20:48 +00001119
Victor Stinnerb64de462017-12-01 18:27:09 +01001120 pathconfig_clear(&_Py_path_config);
1121 _Py_path_config = new_config;
Victor Stinnerd4341102017-11-23 00:12:09 +01001122}
1123
Victor Stinner0327bde2017-11-23 17:03:20 +01001124
Victor Stinnerd4341102017-11-23 00:12:09 +01001125wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001126Py_GetPath(void)
Guido van Rossum667d7041995-08-04 04:20:48 +00001127{
Victor Stinnerb64de462017-12-01 18:27:09 +01001128 pathconfig_global_init();
1129 return _Py_path_config.module_search_path;
Guido van Rossum667d7041995-08-04 04:20:48 +00001130}
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001131
Victor Stinner0327bde2017-11-23 17:03:20 +01001132
Martin v. Löwis790465f2008-04-05 20:41:37 +00001133wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001134Py_GetPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001135{
Victor Stinnerb64de462017-12-01 18:27:09 +01001136 pathconfig_global_init();
1137 return _Py_path_config.prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001138}
1139
Victor Stinner0327bde2017-11-23 17:03:20 +01001140
Martin v. Löwis790465f2008-04-05 20:41:37 +00001141wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001142Py_GetExecPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001143{
Victor Stinnerb64de462017-12-01 18:27:09 +01001144 pathconfig_global_init();
1145 return _Py_path_config.exec_prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001146}
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001147
Victor Stinner0327bde2017-11-23 17:03:20 +01001148
Martin v. Löwis790465f2008-04-05 20:41:37 +00001149wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001150Py_GetProgramFullPath(void)
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001151{
Victor Stinnerb64de462017-12-01 18:27:09 +01001152 pathconfig_global_init();
1153 return _Py_path_config.program_full_path;
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001154}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001155
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001156#ifdef __cplusplus
1157}
1158#endif