blob: 9f5e8b3ff5c6b368cb0bc05cdf63dbe74e892c0c [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 */
120 wchar_t *home; /* PYTHONHOME environment variable */
121 wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
Victor Stinner0327bde2017-11-23 17:03:20 +0100122
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100123 wchar_t *program_name; /* Program name */
Victor Stinner0327bde2017-11-23 17:03:20 +0100124 wchar_t *pythonpath; /* PYTHONPATH define */
125 wchar_t *prefix; /* PREFIX define */
126 wchar_t *exec_prefix; /* EXEC_PREFIX define */
127
128 wchar_t *lib_python; /* "lib/pythonX.Y" */
129 wchar_t argv0_path[MAXPATHLEN+1];
130 wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */
131
132 int prefix_found; /* found platform independent libraries? */
133 int exec_prefix_found; /* found the platform dependent libraries? */
134} PyCalculatePath;
135
136static const wchar_t delimiter[2] = {DELIM, '\0'};
137static const wchar_t separator[2] = {SEP, '\0'};
Victor Stinnerb64de462017-12-01 18:27:09 +0100138static _PyPathConfig _Py_path_config = _PyPathConfig_INIT;
Victor Stinner0327bde2017-11-23 17:03:20 +0100139
Martin v. Löwis790465f2008-04-05 20:41:37 +0000140
Victor Stinner91afbb62015-03-24 12:16:28 +0100141/* Get file status. Encode the path to the locale encoding. */
Victor Stinner91afbb62015-03-24 12:16:28 +0100142static int
143_Py_wstat(const wchar_t* path, struct stat *buf)
144{
145 int err;
146 char *fname;
147 fname = Py_EncodeLocale(path, NULL);
148 if (fname == NULL) {
149 errno = EINVAL;
150 return -1;
151 }
152 err = stat(fname, buf);
153 PyMem_Free(fname);
154 return err;
155}
156
Victor Stinner0327bde2017-11-23 17:03:20 +0100157
Guido van Rossum305e5d01997-04-11 17:18:45 +0000158static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000159reduce(wchar_t *dir)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000160{
Martin v. Löwis790465f2008-04-05 20:41:37 +0000161 size_t i = wcslen(dir);
Fred Drakeedabdc12000-07-08 06:16:37 +0000162 while (i > 0 && dir[i] != SEP)
163 --i;
164 dir[i] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000165}
Guido van Rossumd29806c1998-01-19 22:06:22 +0000166
Victor Stinner0327bde2017-11-23 17:03:20 +0100167
Guido van Rossum305e5d01997-04-11 17:18:45 +0000168static int
Martin v. Löwis790465f2008-04-05 20:41:37 +0000169isfile(wchar_t *filename) /* Is file, not directory */
Guido van Rossum305e5d01997-04-11 17:18:45 +0000170{
Fred Drakeedabdc12000-07-08 06:16:37 +0000171 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100172 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000173 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100174 }
175 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000176 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100177 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000178 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000179}
180
181
182static int
Brett Cannonf299abd2015-04-13 14:21:02 -0400183ismodule(wchar_t *filename) /* Is module -- check for .pyc too */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000184{
Victor Stinner0327bde2017-11-23 17:03:20 +0100185 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000186 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100187 }
Guido van Rossumd29806c1998-01-19 22:06:22 +0000188
Fred Drakeedabdc12000-07-08 06:16:37 +0000189 /* Check for the compiled version of prefix. */
Martin v. Löwis790465f2008-04-05 20:41:37 +0000190 if (wcslen(filename) < MAXPATHLEN) {
Brett Cannonf299abd2015-04-13 14:21:02 -0400191 wcscat(filename, L"c");
Victor Stinner0327bde2017-11-23 17:03:20 +0100192 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000193 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100194 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000195 }
196 return 0;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000197}
198
199
Victor Stinner0327bde2017-11-23 17:03:20 +0100200/* Is executable file */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000201static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100202isxfile(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000203{
Fred Drakeedabdc12000-07-08 06:16:37 +0000204 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100205 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000206 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100207 }
208 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000209 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100210 }
211 if ((buf.st_mode & 0111) == 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000212 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100213 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000214 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000215}
216
217
Victor Stinner0327bde2017-11-23 17:03:20 +0100218/* Is directory */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000219static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100220isdir(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000221{
Fred Drakeedabdc12000-07-08 06:16:37 +0000222 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100223 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000224 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100225 }
226 if (!S_ISDIR(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000227 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100228 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000229 return 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000230}
231
232
Tim Petersec8c5a92004-08-08 01:00:47 +0000233/* Add a path component, by appending stuff to buffer.
234 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
235 NUL-terminated string with no more than MAXPATHLEN characters (not counting
236 the trailing NUL). It's a fatal error if it contains a string longer than
237 that (callers must be careful!). If these requirements are met, it's
238 guaranteed that buffer will still be a NUL-terminated string with no more
239 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
240 stuff as fits will be appended.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000241*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000242static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000243joinpath(wchar_t *buffer, wchar_t *stuff)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000244{
Fred Drakeedabdc12000-07-08 06:16:37 +0000245 size_t n, k;
Victor Stinner0327bde2017-11-23 17:03:20 +0100246 if (stuff[0] == SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000247 n = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100248 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000249 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000250 n = wcslen(buffer);
Victor Stinner0327bde2017-11-23 17:03:20 +0100251 if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000252 buffer[n++] = SEP;
Victor Stinner0327bde2017-11-23 17:03:20 +0100253 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000254 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100255 if (n > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 Py_FatalError("buffer overflow in getpath.c's joinpath()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100257 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000258 k = wcslen(stuff);
Victor Stinner0327bde2017-11-23 17:03:20 +0100259 if (n + k > MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000260 k = MAXPATHLEN - n;
Victor Stinner0327bde2017-11-23 17:03:20 +0100261 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000262 wcsncpy(buffer+n, stuff, k);
Fred Drakeedabdc12000-07-08 06:16:37 +0000263 buffer[n+k] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000264}
265
Victor Stinner0327bde2017-11-23 17:03:20 +0100266
Guido van Rossume296ced2001-09-28 20:00:29 +0000267/* copy_absolute requires that path be allocated at least
268 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000269static void
Victor Stinnerf4061da2010-10-14 12:37:19 +0000270copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000271{
Victor Stinner0327bde2017-11-23 17:03:20 +0100272 if (p[0] == SEP) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000273 wcscpy(path, p);
Victor Stinner0327bde2017-11-23 17:03:20 +0100274 }
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000275 else {
Victor Stinnerf4061da2010-10-14 12:37:19 +0000276 if (!_Py_wgetcwd(path, pathlen)) {
Victor Stinner4f3abb02010-10-07 23:29:18 +0000277 /* unable to get the current directory */
278 wcscpy(path, p);
279 return;
280 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100281 if (p[0] == '.' && p[1] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000282 p += 2;
Victor Stinner0327bde2017-11-23 17:03:20 +0100283 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000284 joinpath(path, p);
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000285 }
286}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000287
Victor Stinner0327bde2017-11-23 17:03:20 +0100288
Guido van Rossume296ced2001-09-28 20:00:29 +0000289/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
290static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000291absolutize(wchar_t *path)
Guido van Rossume296ced2001-09-28 20:00:29 +0000292{
Victor Stinnerf4061da2010-10-14 12:37:19 +0000293 wchar_t buffer[MAXPATHLEN+1];
Guido van Rossume296ced2001-09-28 20:00:29 +0000294
Victor Stinner0327bde2017-11-23 17:03:20 +0100295 if (path[0] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000296 return;
Victor Stinner0327bde2017-11-23 17:03:20 +0100297 }
Victor Stinnerf4061da2010-10-14 12:37:19 +0000298 copy_absolute(buffer, path, MAXPATHLEN+1);
Martin v. Löwis790465f2008-04-05 20:41:37 +0000299 wcscpy(path, buffer);
Guido van Rossume296ced2001-09-28 20:00:29 +0000300}
301
Victor Stinner0327bde2017-11-23 17:03:20 +0100302
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100303/* search for a prefix value in an environment file. If found, copy it
304 to the provided buffer, which is expected to be no more than MAXPATHLEN
305 bytes long.
306*/
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100307static int
308find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
309{
310 int result = 0; /* meaning not found */
311 char buffer[MAXPATHLEN*2+1]; /* allow extra for key, '=', etc. */
312
313 fseek(env_file, 0, SEEK_SET);
314 while (!feof(env_file)) {
315 char * p = fgets(buffer, MAXPATHLEN*2, env_file);
316 wchar_t tmpbuffer[MAXPATHLEN*2+1];
317 PyObject * decoded;
318 int n;
319
Victor Stinner0327bde2017-11-23 17:03:20 +0100320 if (p == NULL) {
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100321 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100322 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100323 n = strlen(p);
324 if (p[n - 1] != '\n') {
325 /* line has overflowed - bail */
326 break;
327 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100328 if (p[0] == '#') {
329 /* Comment - skip */
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100330 continue;
Victor Stinner0327bde2017-11-23 17:03:20 +0100331 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100332 decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
333 if (decoded != NULL) {
334 Py_ssize_t k;
335 wchar_t * state;
336 k = PyUnicode_AsWideChar(decoded,
337 tmpbuffer, MAXPATHLEN * 2);
338 Py_DECREF(decoded);
339 if (k >= 0) {
340 wchar_t * tok = wcstok(tmpbuffer, L" \t\r\n", &state);
341 if ((tok != NULL) && !wcscmp(tok, key)) {
342 tok = wcstok(NULL, L" \t", &state);
343 if ((tok != NULL) && !wcscmp(tok, L"=")) {
344 tok = wcstok(NULL, L"\r\n", &state);
345 if (tok != NULL) {
346 wcsncpy(value, tok, MAXPATHLEN);
347 result = 1;
348 break;
349 }
350 }
351 }
352 }
353 }
354 }
355 return result;
356}
357
Victor Stinner0327bde2017-11-23 17:03:20 +0100358
Guido van Rossume296ced2001-09-28 20:00:29 +0000359/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000360 bytes long.
361*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000362static int
Victor Stinner9316ee42017-11-25 03:17:57 +0100363search_for_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000364{
Fred Drakeedabdc12000-07-08 06:16:37 +0000365 size_t n;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000366 wchar_t *vpath;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000367
Fred Drakeedabdc12000-07-08 06:16:37 +0000368 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinner0327bde2017-11-23 17:03:20 +0100369 if (calculate->home) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100370 wcsncpy(prefix, calculate->home, MAXPATHLEN);
371 prefix[MAXPATHLEN] = L'\0';
372 wchar_t *delim = wcschr(prefix, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100373 if (delim) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000374 *delim = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100375 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100376 joinpath(prefix, calculate->lib_python);
377 joinpath(prefix, LANDMARK);
Fred Drakeedabdc12000-07-08 06:16:37 +0000378 return 1;
379 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000380
Fred Drakeedabdc12000-07-08 06:16:37 +0000381 /* Check to see if argv[0] is in the build directory */
Victor Stinner9316ee42017-11-25 03:17:57 +0100382 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
383 prefix[MAXPATHLEN] = L'\0';
384 joinpath(prefix, L"Modules/Setup");
385 if (isfile(prefix)) {
Neil Schemenauer6cf07022001-01-24 17:13:11 +0000386 /* Check VPATH to see if argv0_path is in the build directory. */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200387 vpath = Py_DecodeLocale(VPATH, NULL);
Victor Stinner21582312010-10-23 00:13:28 +0000388 if (vpath != NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100389 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
390 prefix[MAXPATHLEN] = L'\0';
391 joinpath(prefix, vpath);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200392 PyMem_RawFree(vpath);
Victor Stinner9316ee42017-11-25 03:17:57 +0100393 joinpath(prefix, L"Lib");
394 joinpath(prefix, LANDMARK);
395 if (ismodule(prefix)) {
Victor Stinner21582312010-10-23 00:13:28 +0000396 return -1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100397 }
Victor Stinner21582312010-10-23 00:13:28 +0000398 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000399 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000400
Fred Drakeedabdc12000-07-08 06:16:37 +0000401 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100402 copy_absolute(prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000403 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100404 n = wcslen(prefix);
405 joinpath(prefix, calculate->lib_python);
406 joinpath(prefix, LANDMARK);
407 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000408 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100409 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100410 prefix[n] = L'\0';
411 reduce(prefix);
412 } while (prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000413
Fred Drakeedabdc12000-07-08 06:16:37 +0000414 /* Look at configure's PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100415 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
416 prefix[MAXPATHLEN] = L'\0';
417 joinpath(prefix, calculate->lib_python);
418 joinpath(prefix, LANDMARK);
419 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000420 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100421 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000422
Fred Drakeedabdc12000-07-08 06:16:37 +0000423 /* Fail */
424 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000425}
426
427
Victor Stinner0327bde2017-11-23 17:03:20 +0100428static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100429calculate_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100430{
Victor Stinner9316ee42017-11-25 03:17:57 +0100431 calculate->prefix_found = search_for_prefix(calculate, prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100432 if (!calculate->prefix_found) {
433 if (!Py_FrozenFlag) {
434 fprintf(stderr,
435 "Could not find platform independent libraries <prefix>\n");
436 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100437 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
438 joinpath(prefix, calculate->lib_python);
Victor Stinner0327bde2017-11-23 17:03:20 +0100439 }
440 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100441 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100442 }
443}
444
445
446static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100447calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100448{
449 /* Reduce prefix and exec_prefix to their essence,
450 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
451 * If we're loading relative to the build directory,
452 * return the compiled-in defaults instead.
453 */
454 if (calculate->prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100455 reduce(prefix);
456 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100457 /* The prefix is the root directory, but reduce() chopped
458 * off the "/". */
Victor Stinner9316ee42017-11-25 03:17:57 +0100459 if (!prefix[0]) {
460 wcscpy(prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100461 }
462 }
463 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100464 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100465 }
466}
467
468
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000469/* search_for_exec_prefix requires that argv0_path be no more than
Guido van Rossume296ced2001-09-28 20:00:29 +0000470 MAXPATHLEN bytes long.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000471*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000472static int
Victor Stinner9316ee42017-11-25 03:17:57 +0100473search_for_exec_prefix(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 Stinner0327bde2017-11-23 17:03:20 +0100478 if (calculate->home) {
479 wchar_t *delim = wcschr(calculate->home, DELIM);
480 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 Stinner9316ee42017-11-25 03:17:57 +0100484 wcsncpy(exec_prefix, calculate->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 Stinner9316ee42017-11-25 03:17:57 +0100555calculate_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100556{
Victor Stinner9316ee42017-11-25 03:17:57 +0100557 calculate->exec_prefix_found = search_for_exec_prefix(calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100558 if (!calculate->exec_prefix_found) {
559 if (!Py_FrozenFlag) {
560 fprintf(stderr,
561 "Could not find platform dependent libraries <exec_prefix>\n");
562 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100563 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
564 joinpath(exec_prefix, L"lib/lib-dynload");
Victor Stinner0327bde2017-11-23 17:03:20 +0100565 }
566 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
567}
568
569
570static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100571calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100572{
573 if (calculate->exec_prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100574 reduce(exec_prefix);
575 reduce(exec_prefix);
576 reduce(exec_prefix);
577 if (!exec_prefix[0]) {
578 wcscpy(exec_prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100579 }
580 }
581 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100582 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100583 }
584}
585
586
Victor Stinner9316ee42017-11-25 03:17:57 +0100587static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100588calculate_program_full_path(PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100589{
Victor Stinnerb64de462017-12-01 18:27:09 +0100590 wchar_t program_full_path[MAXPATHLEN+1];
591 memset(program_full_path, 0, sizeof(program_full_path));
Victor Stinner9316ee42017-11-25 03:17:57 +0100592
Victor Stinnerb9197952017-11-23 19:02:04 +0100593#ifdef __APPLE__
594#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
595 uint32_t nsexeclength = MAXPATHLEN;
596#else
597 unsigned long nsexeclength = MAXPATHLEN;
598#endif
599 char execpath[MAXPATHLEN+1];
600#endif
601
Victor Stinner0327bde2017-11-23 17:03:20 +0100602 /* If there is no slash in the argv0 path, then we have to
603 * assume python is on the user's $PATH, since there's no
604 * other way to find a directory to start the search from. If
605 * $PATH isn't exported, you lose.
606 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100607 if (wcschr(calculate->program_name, SEP)) {
Victor Stinnerb64de462017-12-01 18:27:09 +0100608 wcsncpy(program_full_path, calculate->program_name, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100609 }
Jack Jansen1afd4802004-06-03 14:33:03 +0000610#ifdef __APPLE__
Jack Jansen1afd4802004-06-03 14:33:03 +0000611 /* On Mac OS X, if a script uses an interpreter of the form
612 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
613 * as argv[0], which falls through to the $PATH search below.
614 * If /opt/python2.3/bin isn't in your path, or is near the end,
615 * this algorithm may incorrectly find /usr/bin/python. To work
616 * around this, we can use _NSGetExecutablePath to get a better
617 * hint of what the intended interpreter was, although this
618 * will fail if a relative path was used. but in that case,
619 * absolutize() should help us out below
620 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100621 else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
622 execpath[0] == SEP)
623 {
Victor Stinnerb64de462017-12-01 18:27:09 +0100624 size_t r = mbstowcs(program_full_path, execpath, MAXPATHLEN+1);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000625 if (r == (size_t)-1 || r > MAXPATHLEN) {
626 /* Could not convert execpath, or it's too long. */
Victor Stinnerb64de462017-12-01 18:27:09 +0100627 program_full_path[0] = '\0';
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000629 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000630#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100631 else if (calculate->path_env) {
632 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000633 while (1) {
634 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000635
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000636 if (delim) {
637 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100638 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000639 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100640 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100641 wcsncpy(program_full_path, path, len);
642 program_full_path[len] = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000643 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100644 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100645 wcsncpy(program_full_path, path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100646 }
Jack Jansen55070f52001-12-02 23:56:28 +0000647
Victor Stinnerb64de462017-12-01 18:27:09 +0100648 joinpath(program_full_path, calculate->program_name);
649 if (isxfile(program_full_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000650 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100651 }
Jack Jansen55070f52001-12-02 23:56:28 +0000652
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000653 if (!delim) {
Victor Stinnerb64de462017-12-01 18:27:09 +0100654 program_full_path[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000655 break;
656 }
657 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000659 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100660 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100661 program_full_path[0] = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100662 }
Victor Stinnerb64de462017-12-01 18:27:09 +0100663 if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
664 absolutize(program_full_path);
Victor Stinner0327bde2017-11-23 17:03:20 +0100665 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100666
Victor Stinnerb64de462017-12-01 18:27:09 +0100667 config->program_full_path = _PyMem_RawWcsdup(program_full_path);
668 if (config->program_full_path == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100669 return _Py_INIT_NO_MEMORY();
670 }
671 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100672}
673
674
Victor Stinner9316ee42017-11-25 03:17:57 +0100675static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100676calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path)
Victor Stinner0327bde2017-11-23 17:03:20 +0100677{
Victor Stinnerb64de462017-12-01 18:27:09 +0100678 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100679 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000680
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000681#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100682 NSModule pythonModule;
683
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000684 /* On Mac OS X we have a special case if we're running from a framework.
685 ** This is because the python home should be set relative to the library,
686 ** which is in the framework, not relative to the executable, which may
687 ** be outside of the framework. Except when we're in the build directory...
688 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000689 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
690 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100691 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100692 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000693 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000694 /* See if we might be in the build directory. The framework in the
695 ** build directory is incomplete, it only has the .dylib and a few
696 ** needed symlinks, it doesn't have the Lib directories and such.
697 ** If we're running with the framework from the build directory we must
698 ** be running the interpreter in the build directory, so we use the
699 ** build-directory-specific logic to find Lib and such.
700 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100701 size_t len;
702 wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100703 if (wbuf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100704 return DECODE_LOCALE_ERR("framework location", len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100705 }
706
Victor Stinner0327bde2017-11-23 17:03:20 +0100707 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
708 reduce(calculate->argv0_path);
709 joinpath(calculate->argv0_path, calculate->lib_python);
710 joinpath(calculate->argv0_path, LANDMARK);
711 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000712 /* We are in the build directory so use the name of the
713 executable - we know that the absolute path is passed */
Victor Stinnerb64de462017-12-01 18:27:09 +0100714 wcsncpy(calculate->argv0_path, program_full_path, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000715 }
716 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100717 /* Use the location of the library as the program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100718 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000719 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200720 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000721 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000722#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000723
Guido van Rossum305e5d01997-04-11 17:18:45 +0000724#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100725 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinnerb64de462017-12-01 18:27:09 +0100726 int linklen = _Py_wreadlink(program_full_path, tmpbuffer, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100727 while (linklen != -1) {
728 if (tmpbuffer[0] == SEP) {
729 /* tmpbuffer should never be longer than MAXPATHLEN,
730 but extra check does not hurt */
731 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000732 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100733 else {
Victor Stinnerb64de462017-12-01 18:27:09 +0100734 /* Interpret relative to program_full_path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100735 reduce(calculate->argv0_path);
736 joinpath(calculate->argv0_path, tmpbuffer);
737 }
738 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000739 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000740#endif /* HAVE_READLINK */
741
Victor Stinner0327bde2017-11-23 17:03:20 +0100742 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000743 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100744 MAXPATHLEN bytes long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100745 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100746}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000747
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100748
Victor Stinner0327bde2017-11-23 17:03:20 +0100749/* Search for an "pyvenv.cfg" environment configuration file, first in the
750 executable's directory and then in the parent directory.
751 If found, open it for use when searching for prefixes.
752*/
753static void
754calculate_read_pyenv(PyCalculatePath *calculate)
755{
756 wchar_t tmpbuffer[MAXPATHLEN+1];
757 wchar_t *env_cfg = L"pyvenv.cfg";
758 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100759
Victor Stinner0327bde2017-11-23 17:03:20 +0100760 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100761
Victor Stinner0327bde2017-11-23 17:03:20 +0100762 joinpath(tmpbuffer, env_cfg);
763 env_file = _Py_wfopen(tmpbuffer, L"r");
764 if (env_file == NULL) {
765 errno = 0;
766
767 reduce(tmpbuffer);
768 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100769 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100770
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100771 env_file = _Py_wfopen(tmpbuffer, L"r");
772 if (env_file == NULL) {
773 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100774 }
775 }
776
Victor Stinner0327bde2017-11-23 17:03:20 +0100777 if (env_file == NULL) {
778 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000779 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000780
Victor Stinner0327bde2017-11-23 17:03:20 +0100781 /* Look for a 'home' variable and set argv0_path to it, if found */
782 if (find_env_config_value(env_file, L"home", tmpbuffer)) {
783 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000784 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100785 fclose(env_file);
786}
Just van Rossum52e14d62002-12-30 22:08:05 +0000787
Guido van Rossum305e5d01997-04-11 17:18:45 +0000788
Victor Stinner0327bde2017-11-23 17:03:20 +0100789static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100790calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100791{
Victor Stinner9316ee42017-11-25 03:17:57 +0100792 wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100793 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000794
Victor Stinner0327bde2017-11-23 17:03:20 +0100795 if (calculate->prefix_found > 0) {
796 /* Use the reduced prefix returned by Py_GetPrefix() */
797 reduce(calculate->zip_path);
798 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100799 }
800 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100801 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
802 }
803 joinpath(calculate->zip_path, L"lib/python00.zip");
804
805 /* Replace "00" with version */
806 size_t bufsz = wcslen(calculate->zip_path);
807 calculate->zip_path[bufsz - 6] = VERSION[0];
808 calculate->zip_path[bufsz - 5] = VERSION[2];
809}
810
811
Victor Stinner9316ee42017-11-25 03:17:57 +0100812static _PyInitError
813calculate_module_search_path(PyCalculatePath *calculate,
814 const wchar_t *prefix, const wchar_t *exec_prefix,
Victor Stinnerb64de462017-12-01 18:27:09 +0100815 _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100816{
817 /* Calculate size of return buffer */
818 size_t bufsz = 0;
819 if (calculate->module_search_path_env != NULL) {
820 bufsz += wcslen(calculate->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000821 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000822
Victor Stinner0327bde2017-11-23 17:03:20 +0100823 wchar_t *defpath = calculate->pythonpath;
Victor Stinner9316ee42017-11-25 03:17:57 +0100824 size_t prefixsz = wcslen(prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000825 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000826 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000827
Victor Stinner0327bde2017-11-23 17:03:20 +0100828 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000829 /* Paths are relative to prefix */
830 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100831 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000832
Victor Stinner0327bde2017-11-23 17:03:20 +0100833 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000834 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100835 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000836 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000837 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000838 break;
839 }
840 defpath = delim + 1;
841 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000842
Victor Stinner0327bde2017-11-23 17:03:20 +0100843 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner9316ee42017-11-25 03:17:57 +0100844 bufsz += wcslen(exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000845
Victor Stinner0327bde2017-11-23 17:03:20 +0100846 /* Allocate the buffer */
847 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000848 if (buf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100849 return _Py_INIT_NO_MEMORY();
Fred Drakeedabdc12000-07-08 06:16:37 +0000850 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100851 buf[0] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000852
Victor Stinner72967a42013-11-16 01:22:04 +0100853 /* Run-time value of $PYTHONPATH goes first */
Victor Stinner0327bde2017-11-23 17:03:20 +0100854 if (calculate->module_search_path_env) {
855 wcscpy(buf, calculate->module_search_path_env);
856 wcscat(buf, delimiter);
Fred Drakeedabdc12000-07-08 06:16:37 +0000857 }
Victor Stinner72967a42013-11-16 01:22:04 +0100858
859 /* Next is the default zip path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100860 wcscat(buf, calculate->zip_path);
Victor Stinner72967a42013-11-16 01:22:04 +0100861 wcscat(buf, delimiter);
862
863 /* Next goes merge of compile-time $PYTHONPATH with
864 * dynamically located prefix.
865 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100866 defpath = calculate->pythonpath;
Victor Stinner72967a42013-11-16 01:22:04 +0100867 while (1) {
868 wchar_t *delim = wcschr(defpath, DELIM);
869
870 if (defpath[0] != SEP) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100871 wcscat(buf, prefix);
872 if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
Victor Stinner0327bde2017-11-23 17:03:20 +0100873 defpath[0] != (delim ? DELIM : L'\0'))
874 {
875 /* not empty */
Serhiy Storchaka62e32d62016-11-11 12:05:01 +0200876 wcscat(buf, separator);
877 }
Victor Stinner72967a42013-11-16 01:22:04 +0100878 }
879
880 if (delim) {
881 size_t len = delim - defpath + 1;
882 size_t end = wcslen(buf) + len;
883 wcsncat(buf, defpath, len);
Victor Stinner9316ee42017-11-25 03:17:57 +0100884 buf[end] = '\0';
Victor Stinner72967a42013-11-16 01:22:04 +0100885 }
886 else {
887 wcscat(buf, defpath);
888 break;
889 }
890 defpath = delim + 1;
891 }
892 wcscat(buf, delimiter);
893
894 /* Finally, on goes the directory for dynamic-load modules */
Victor Stinner9316ee42017-11-25 03:17:57 +0100895 wcscat(buf, exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100896
Victor Stinner9316ee42017-11-25 03:17:57 +0100897 config->module_search_path = buf;
898 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100899}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000900
Victor Stinner0327bde2017-11-23 17:03:20 +0100901
Victor Stinner0327bde2017-11-23 17:03:20 +0100902static _PyInitError
903calculate_init(PyCalculatePath *calculate,
904 const _PyMainInterpreterConfig *main_config)
905{
Victor Stinner46972b72017-11-24 22:55:40 +0100906 calculate->home = main_config->home;
907 calculate->module_search_path_env = main_config->module_search_path_env;
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100908 calculate->program_name = main_config->program_name;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000909
Victor Stinner0327bde2017-11-23 17:03:20 +0100910 size_t len;
911 char *path = getenv("PATH");
912 if (path) {
913 calculate->path_env = Py_DecodeLocale(path, &len);
914 if (!calculate->path_env) {
Victor Stinner46972b72017-11-24 22:55:40 +0100915 return DECODE_LOCALE_ERR("PATH environment variable", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100916 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000917 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000918
Victor Stinner0327bde2017-11-23 17:03:20 +0100919 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
920 if (!calculate->pythonpath) {
Victor Stinner46972b72017-11-24 22:55:40 +0100921 return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100922 }
923 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
924 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100925 return DECODE_LOCALE_ERR("PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100926 }
927 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
928 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100929 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100930 }
931 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
932 if (!calculate->lib_python) {
Victor Stinner46972b72017-11-24 22:55:40 +0100933 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100934 }
935 return _Py_INIT_OK();
936}
937
938
939static void
940calculate_free(PyCalculatePath *calculate)
941{
942 PyMem_RawFree(calculate->pythonpath);
943 PyMem_RawFree(calculate->prefix);
944 PyMem_RawFree(calculate->exec_prefix);
945 PyMem_RawFree(calculate->lib_python);
946 PyMem_RawFree(calculate->path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100947}
948
949
Victor Stinner9316ee42017-11-25 03:17:57 +0100950static _PyInitError
Victor Stinnerb64de462017-12-01 18:27:09 +0100951calculate_path_impl(PyCalculatePath *calculate, _PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100952{
Victor Stinnerb64de462017-12-01 18:27:09 +0100953 _PyInitError err = calculate_program_full_path(calculate, config);
Victor Stinner9316ee42017-11-25 03:17:57 +0100954 if (_Py_INIT_FAILED(err)) {
955 return err;
956 }
957
Victor Stinnerb64de462017-12-01 18:27:09 +0100958 err = calculate_argv0_path(calculate, config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100959 if (_Py_INIT_FAILED(err)) {
960 return err;
961 }
962
Victor Stinner0327bde2017-11-23 17:03:20 +0100963 calculate_read_pyenv(calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100964
965 wchar_t prefix[MAXPATHLEN+1];
966 memset(prefix, 0, sizeof(prefix));
967 calculate_prefix(calculate, prefix);
968
969 calculate_zip_path(calculate, prefix);
970
971 wchar_t exec_prefix[MAXPATHLEN+1];
972 memset(exec_prefix, 0, sizeof(exec_prefix));
973 calculate_exec_prefix(calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100974
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100975 if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
976 !Py_FrozenFlag)
977 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100978 fprintf(stderr,
979 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
980 }
981
Victor Stinner9316ee42017-11-25 03:17:57 +0100982 err = calculate_module_search_path(calculate, prefix, exec_prefix,
983 config);
984 if (_Py_INIT_FAILED(err)) {
985 return err;
986 }
987
988 calculate_reduce_prefix(calculate, prefix);
989
990 config->prefix = _PyMem_RawWcsdup(prefix);
991 if (config->prefix == NULL) {
992 return _Py_INIT_NO_MEMORY();
993 }
994
995 calculate_reduce_exec_prefix(calculate, exec_prefix);
996
997 config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
998 if (config->exec_prefix == NULL) {
999 return _Py_INIT_NO_MEMORY();
1000 }
1001
1002 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001003}
1004
1005
1006static void
Victor Stinnerb64de462017-12-01 18:27:09 +01001007pathconfig_clear(_PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +01001008{
Victor Stinner9316ee42017-11-25 03:17:57 +01001009#define CLEAR(ATTR) \
1010 do { \
1011 PyMem_RawFree(ATTR); \
1012 ATTR = NULL; \
1013 } while (0)
1014
1015 CLEAR(config->prefix);
1016 CLEAR(config->exec_prefix);
Victor Stinnerb64de462017-12-01 18:27:09 +01001017 CLEAR(config->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +01001018 CLEAR(config->module_search_path);
1019#undef CLEAR
1020}
1021
1022
1023/* Initialize paths for Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix()
1024 and Py_GetProgramFullPath() */
1025_PyInitError
1026_PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
1027{
Victor Stinnerb64de462017-12-01 18:27:09 +01001028 if (_Py_path_config.module_search_path) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001029 /* Already initialized */
1030 return _Py_INIT_OK();
1031 }
1032
Victor Stinner0327bde2017-11-23 17:03:20 +01001033 PyCalculatePath calculate;
1034 memset(&calculate, 0, sizeof(calculate));
1035
Victor Stinner9316ee42017-11-25 03:17:57 +01001036 _PyInitError err = calculate_init(&calculate, main_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001037 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001038 goto done;
Victor Stinner0327bde2017-11-23 17:03:20 +01001039 }
1040
Victor Stinnerb64de462017-12-01 18:27:09 +01001041 _PyPathConfig new_path_config;
Victor Stinner0327bde2017-11-23 17:03:20 +01001042 memset(&new_path_config, 0, sizeof(new_path_config));
1043
Victor Stinner9316ee42017-11-25 03:17:57 +01001044 err = calculate_path_impl(&calculate, &new_path_config);
1045 if (_Py_INIT_FAILED(err)) {
1046 pathconfig_clear(&new_path_config);
1047 goto done;
1048 }
1049
Victor Stinnerb64de462017-12-01 18:27:09 +01001050 _Py_path_config = new_path_config;
Victor Stinner9316ee42017-11-25 03:17:57 +01001051 err = _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001052
Victor Stinner9316ee42017-11-25 03:17:57 +01001053done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001054 calculate_free(&calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +01001055 return err;
1056}
Victor Stinner46972b72017-11-24 22:55:40 +01001057
Victor Stinner9316ee42017-11-25 03:17:57 +01001058
1059static void
Victor Stinnerb64de462017-12-01 18:27:09 +01001060pathconfig_global_init(void)
Victor Stinner9316ee42017-11-25 03:17:57 +01001061{
Victor Stinnerb64de462017-12-01 18:27:09 +01001062 if (_Py_path_config.module_search_path) {
1063 /* Already initialized */
1064 return;
1065 }
1066
Victor Stinner9316ee42017-11-25 03:17:57 +01001067 _PyInitError err;
1068 _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
1069
1070 err = _PyMainInterpreterConfig_ReadEnv(&config);
1071 if (!_Py_INIT_FAILED(err)) {
1072 err = _PyPathConfig_Init(&config);
Victor Stinner46972b72017-11-24 22:55:40 +01001073 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001074 _PyMainInterpreterConfig_Clear(&config);
1075
1076 if (_Py_INIT_FAILED(err)) {
1077 _Py_FatalInitError(err);
1078 }
1079}
1080
1081
1082void
1083_PyPathConfig_Fini(void)
1084{
Victor Stinnerb64de462017-12-01 18:27:09 +01001085 pathconfig_clear(&_Py_path_config);
Guido van Rossum305e5d01997-04-11 17:18:45 +00001086}
1087
1088
1089/* External interface */
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +00001090void
1091Py_SetPath(const wchar_t *path)
1092{
Victor Stinner0327bde2017-11-23 17:03:20 +01001093 if (path == NULL) {
Victor Stinnerb64de462017-12-01 18:27:09 +01001094 pathconfig_clear(&_Py_path_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001095 return;
1096 }
1097
Victor Stinnerb64de462017-12-01 18:27:09 +01001098 _PyPathConfig new_config;
1099 new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
Victor Stinner9316ee42017-11-25 03:17:57 +01001100 new_config.exec_prefix = _PyMem_RawWcsdup(L"");
1101 new_config.prefix = _PyMem_RawWcsdup(L"");
1102 new_config.module_search_path = _PyMem_RawWcsdup(path);
Guido van Rossum667d7041995-08-04 04:20:48 +00001103
Victor Stinnerb64de462017-12-01 18:27:09 +01001104 pathconfig_clear(&_Py_path_config);
1105 _Py_path_config = new_config;
Victor Stinnerd4341102017-11-23 00:12:09 +01001106}
1107
Victor Stinner0327bde2017-11-23 17:03:20 +01001108
Victor Stinnerd4341102017-11-23 00:12:09 +01001109wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001110Py_GetPath(void)
Guido van Rossum667d7041995-08-04 04:20:48 +00001111{
Victor Stinnerb64de462017-12-01 18:27:09 +01001112 pathconfig_global_init();
1113 return _Py_path_config.module_search_path;
Guido van Rossum667d7041995-08-04 04:20:48 +00001114}
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001115
Victor Stinner0327bde2017-11-23 17:03:20 +01001116
Martin v. Löwis790465f2008-04-05 20:41:37 +00001117wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001118Py_GetPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001119{
Victor Stinnerb64de462017-12-01 18:27:09 +01001120 pathconfig_global_init();
1121 return _Py_path_config.prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001122}
1123
Victor Stinner0327bde2017-11-23 17:03:20 +01001124
Martin v. Löwis790465f2008-04-05 20:41:37 +00001125wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001126Py_GetExecPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001127{
Victor Stinnerb64de462017-12-01 18:27:09 +01001128 pathconfig_global_init();
1129 return _Py_path_config.exec_prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001130}
Guido van Rossum7929c6f1997-05-20 22:38:21 +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_GetProgramFullPath(void)
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001135{
Victor Stinnerb64de462017-12-01 18:27:09 +01001136 pathconfig_global_init();
1137 return _Py_path_config.program_full_path;
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001138}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001139
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001140#ifdef __cplusplus
1141}
1142#endif