blob: 02d626cea73b38ef5f9a5540f6bdb92c2d4e9f80 [file] [log] [blame]
Guido van Rossum582646a1996-05-28 22:30:17 +00001/* Return the initial module search path. */
2
Guido van Rossum667d7041995-08-04 04:20:48 +00003#include "Python.h"
4#include "osdefs.h"
5
Guido van Rossum305e5d01997-04-11 17:18:45 +00006#include <sys/types.h>
Guido van Rossum21f84971997-06-02 22:18:31 +00007#include <string.h>
Guido van Rossum667d7041995-08-04 04:20:48 +00008
Brett Cannonf6af76d2004-06-26 04:03:06 +00009#ifdef __APPLE__
Victor Stinner0327bde2017-11-23 17:03:20 +010010# include <mach-o/dyld.h>
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011#endif
12
Guido van Rossum305e5d01997-04-11 17:18:45 +000013/* Search in some common locations for the associated Python libraries.
14 *
15 * Two directories must be found, the platform independent directory
Barry Warsaw90126031997-04-11 20:27:03 +000016 * (prefix), containing the common .py and .pyc files, and the platform
17 * dependent directory (exec_prefix), containing the shared library
18 * modules. Note that prefix and exec_prefix can be the same directory,
19 * but for some installations, they are different.
Guido van Rossum305e5d01997-04-11 17:18:45 +000020 *
Barry Warsaw90126031997-04-11 20:27:03 +000021 * Py_GetPath() carries out separate searches for prefix and exec_prefix.
22 * Each search tries a number of different locations until a ``landmark''
23 * file or directory is found. If no prefix or exec_prefix is found, a
24 * warning message is issued and the preprocessor defined PREFIX and
25 * EXEC_PREFIX are used (even though they will not work); python carries on
26 * as best as is possible, but most imports will fail.
Guido van Rossum305e5d01997-04-11 17:18:45 +000027 *
28 * Before any searches are done, the location of the executable is
Guido van Rossumd8faa362007-04-27 19:54:29 +000029 * determined. If argv[0] has one or more slashes in it, it is used
Barry Warsaw90126031997-04-11 20:27:03 +000030 * unchanged. Otherwise, it must have been invoked from the shell's path,
31 * so we search $PATH for the named executable and use that. If the
32 * executable was not found on $PATH (or there was no $PATH environment
33 * variable), the original argv[0] string is used.
Guido van Rossum305e5d01997-04-11 17:18:45 +000034 *
Barry Warsaw90126031997-04-11 20:27:03 +000035 * Next, the executable location is examined to see if it is a symbolic
36 * link. If so, the link is chased (correctly interpreting a relative
37 * pathname if one is found) and the directory of the link target is used.
Guido van Rossum305e5d01997-04-11 17:18:45 +000038 *
Barry Warsaw90126031997-04-11 20:27:03 +000039 * Finally, argv0_path is set to the directory containing the executable
40 * (i.e. the last component is stripped).
Guido van Rossum305e5d01997-04-11 17:18:45 +000041 *
Barry Warsaw90126031997-04-11 20:27:03 +000042 * With argv0_path in hand, we perform a number of steps. The same steps
43 * are performed for prefix and for exec_prefix, but with a different
44 * landmark.
Guido van Rossum305e5d01997-04-11 17:18:45 +000045 *
46 * Step 1. Are we running python out of the build directory? This is
47 * checked by looking for a different kind of landmark relative to
Barry Warsaw90126031997-04-11 20:27:03 +000048 * argv0_path. For prefix, the landmark's path is derived from the VPATH
49 * preprocessor variable (taking into account that its value is almost, but
50 * not quite, what we need). For exec_prefix, the landmark is
Antoine Pitroueba57b62010-08-14 12:33:18 +000051 * pybuilddir.txt. If the landmark is found, we're done.
Guido van Rossum305e5d01997-04-11 17:18:45 +000052 *
53 * For the remaining steps, the prefix landmark will always be
Jeremy Hylton847a9962000-05-26 21:49:07 +000054 * lib/python$VERSION/os.py and the exec_prefix will always be
Guido van Rossum266033e1997-10-20 23:20:32 +000055 * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
Barry Warsaw90126031997-04-11 20:27:03 +000056 * number as supplied by the Makefile. Note that this means that no more
57 * build directory checking is performed; if the first step did not find
58 * the landmarks, the assumption is that python is running from an
59 * installed setup.
Guido van Rossum305e5d01997-04-11 17:18:45 +000060 *
61 * Step 2. See if the $PYTHONHOME environment variable points to the
Barry Warsaw90126031997-04-11 20:27:03 +000062 * installed location of the Python libraries. If $PYTHONHOME is set, then
63 * it points to prefix and exec_prefix. $PYTHONHOME can be a single
64 * directory, which is used for both, or the prefix and exec_prefix
65 * directories separated by a colon.
Guido van Rossum305e5d01997-04-11 17:18:45 +000066 *
67 * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
Barry Warsaw90126031997-04-11 20:27:03 +000068 * backtracking up the path until it is exhausted. This is the most common
69 * step to succeed. Note that if prefix and exec_prefix are different,
70 * exec_prefix is more likely to be found; however if exec_prefix is a
71 * subdirectory of prefix, both will be found.
Guido van Rossum305e5d01997-04-11 17:18:45 +000072 *
Barry Warsaw90126031997-04-11 20:27:03 +000073 * Step 4. Search the directories pointed to by the preprocessor variables
74 * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be
75 * passed in as options to the configure script.
Guido van Rossum305e5d01997-04-11 17:18:45 +000076 *
Barry Warsaw90126031997-04-11 20:27:03 +000077 * That's it!
78 *
79 * Well, almost. Once we have determined prefix and exec_prefix, the
Thomas Wouters7e474022000-07-16 12:04:32 +000080 * preprocessor variable PYTHONPATH is used to construct a path. Each
Barry Warsaw90126031997-04-11 20:27:03 +000081 * relative path on PYTHONPATH is prefixed with prefix. Then the directory
82 * containing the shared library modules is appended. The environment
83 * variable $PYTHONPATH is inserted in front of it all. Finally, the
84 * prefix and exec_prefix globals are tweaked so they reflect the values
85 * expected by other code, by stripping the "lib/python$VERSION/..." stuff
86 * off. If either points to the build directory, the globals are reset to
87 * the corresponding preprocessor variables (so sys.prefix will reflect the
88 * installation location, even though sys.path points into the build
89 * directory). This seems to make more sense given that currently the only
90 * known use of sys.prefix and sys.exec_prefix is for the ILU installation
91 * process to find the installed Python tree.
Antoine Pitroueba57b62010-08-14 12:33:18 +000092 *
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +000093 * An embedding application can use Py_SetPath() to override all of
94 * these authomatic path computations.
95 *
Antoine Pitroueba57b62010-08-14 12:33:18 +000096 * NOTE: Windows MSVC builds use PC/getpathp.c instead!
Barry Warsaw90126031997-04-11 20:27:03 +000097 */
Guido van Rossum305e5d01997-04-11 17:18:45 +000098
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000099#ifdef __cplusplus
Victor Stinner0327bde2017-11-23 17:03:20 +0100100extern "C" {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000101#endif
102
103
Benjamin Petersonf5854142016-06-02 12:41:35 -0700104#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH)
105#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined"
Guido van Rossum305e5d01997-04-11 17:18:45 +0000106#endif
Guido van Rossum667d7041995-08-04 04:20:48 +0000107
Guido van Rossum305e5d01997-04-11 17:18:45 +0000108#ifndef LANDMARK
Martin v. Löwis790465f2008-04-05 20:41:37 +0000109#define LANDMARK L"os.py"
Guido van Rossum305e5d01997-04-11 17:18:45 +0000110#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000111
Victor Stinner9316ee42017-11-25 03:17:57 +0100112#define DECODE_LOCALE_ERR(NAME, LEN) \
113 ((LEN) == (size_t)-2) \
114 ? _Py_INIT_USER_ERR("cannot decode " #NAME) \
115 : _Py_INIT_NO_MEMORY()
116
117
Victor Stinner0327bde2017-11-23 17:03:20 +0100118typedef struct {
Victor Stinner9316ee42017-11-25 03:17:57 +0100119 wchar_t *prefix;
120 wchar_t *exec_prefix;
121 wchar_t *program_name;
Victor Stinner0327bde2017-11-23 17:03:20 +0100122 wchar_t *module_search_path;
123} PyPathConfig;
124
125typedef struct {
126 wchar_t *path_env; /* PATH environment variable */
127 wchar_t *home; /* PYTHONHOME environment variable */
128 wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
Victor Stinner0327bde2017-11-23 17:03:20 +0100129
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100130 wchar_t *program_name; /* Program name */
Victor Stinner0327bde2017-11-23 17:03:20 +0100131 wchar_t *pythonpath; /* PYTHONPATH define */
132 wchar_t *prefix; /* PREFIX define */
133 wchar_t *exec_prefix; /* EXEC_PREFIX define */
134
135 wchar_t *lib_python; /* "lib/pythonX.Y" */
136 wchar_t argv0_path[MAXPATHLEN+1];
137 wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */
138
139 int prefix_found; /* found platform independent libraries? */
140 int exec_prefix_found; /* found the platform dependent libraries? */
141} PyCalculatePath;
142
143static const wchar_t delimiter[2] = {DELIM, '\0'};
144static const wchar_t separator[2] = {SEP, '\0'};
145static PyPathConfig path_config = {.module_search_path = NULL};
146
Martin v. Löwis790465f2008-04-05 20:41:37 +0000147
Victor Stinner91afbb62015-03-24 12:16:28 +0100148/* Get file status. Encode the path to the locale encoding. */
Victor Stinner91afbb62015-03-24 12:16:28 +0100149static int
150_Py_wstat(const wchar_t* path, struct stat *buf)
151{
152 int err;
153 char *fname;
154 fname = Py_EncodeLocale(path, NULL);
155 if (fname == NULL) {
156 errno = EINVAL;
157 return -1;
158 }
159 err = stat(fname, buf);
160 PyMem_Free(fname);
161 return err;
162}
163
Victor Stinner0327bde2017-11-23 17:03:20 +0100164
Guido van Rossum305e5d01997-04-11 17:18:45 +0000165static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000166reduce(wchar_t *dir)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000167{
Martin v. Löwis790465f2008-04-05 20:41:37 +0000168 size_t i = wcslen(dir);
Fred Drakeedabdc12000-07-08 06:16:37 +0000169 while (i > 0 && dir[i] != SEP)
170 --i;
171 dir[i] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000172}
Guido van Rossumd29806c1998-01-19 22:06:22 +0000173
Victor Stinner0327bde2017-11-23 17:03:20 +0100174
Guido van Rossum305e5d01997-04-11 17:18:45 +0000175static int
Martin v. Löwis790465f2008-04-05 20:41:37 +0000176isfile(wchar_t *filename) /* Is file, not directory */
Guido van Rossum305e5d01997-04-11 17:18:45 +0000177{
Fred Drakeedabdc12000-07-08 06:16:37 +0000178 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100179 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000180 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100181 }
182 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000183 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100184 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000185 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000186}
187
188
189static int
Brett Cannonf299abd2015-04-13 14:21:02 -0400190ismodule(wchar_t *filename) /* Is module -- check for .pyc too */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000191{
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 }
Guido van Rossumd29806c1998-01-19 22:06:22 +0000195
Fred Drakeedabdc12000-07-08 06:16:37 +0000196 /* Check for the compiled version of prefix. */
Martin v. Löwis790465f2008-04-05 20:41:37 +0000197 if (wcslen(filename) < MAXPATHLEN) {
Brett Cannonf299abd2015-04-13 14:21:02 -0400198 wcscat(filename, L"c");
Victor Stinner0327bde2017-11-23 17:03:20 +0100199 if (isfile(filename)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000200 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100201 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000202 }
203 return 0;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000204}
205
206
Victor Stinner0327bde2017-11-23 17:03:20 +0100207/* Is executable file */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000208static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100209isxfile(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000210{
Fred Drakeedabdc12000-07-08 06:16:37 +0000211 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100212 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000213 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100214 }
215 if (!S_ISREG(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000216 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100217 }
218 if ((buf.st_mode & 0111) == 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000219 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100220 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000221 return 1;
Guido van Rossumd29806c1998-01-19 22:06:22 +0000222}
223
224
Victor Stinner0327bde2017-11-23 17:03:20 +0100225/* Is directory */
Guido van Rossumd29806c1998-01-19 22:06:22 +0000226static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100227isdir(wchar_t *filename)
Guido van Rossumd29806c1998-01-19 22:06:22 +0000228{
Fred Drakeedabdc12000-07-08 06:16:37 +0000229 struct stat buf;
Victor Stinner0327bde2017-11-23 17:03:20 +0100230 if (_Py_wstat(filename, &buf) != 0) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000231 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100232 }
233 if (!S_ISDIR(buf.st_mode)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000234 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100235 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000236 return 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000237}
238
239
Tim Petersec8c5a92004-08-08 01:00:47 +0000240/* Add a path component, by appending stuff to buffer.
241 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
242 NUL-terminated string with no more than MAXPATHLEN characters (not counting
243 the trailing NUL). It's a fatal error if it contains a string longer than
244 that (callers must be careful!). If these requirements are met, it's
245 guaranteed that buffer will still be a NUL-terminated string with no more
246 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
247 stuff as fits will be appended.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000248*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000249static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000250joinpath(wchar_t *buffer, wchar_t *stuff)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000251{
Fred Drakeedabdc12000-07-08 06:16:37 +0000252 size_t n, k;
Victor Stinner0327bde2017-11-23 17:03:20 +0100253 if (stuff[0] == SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000254 n = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100255 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000256 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000257 n = wcslen(buffer);
Victor Stinner0327bde2017-11-23 17:03:20 +0100258 if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000259 buffer[n++] = SEP;
Victor Stinner0327bde2017-11-23 17:03:20 +0100260 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000261 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100262 if (n > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 Py_FatalError("buffer overflow in getpath.c's joinpath()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100264 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000265 k = wcslen(stuff);
Victor Stinner0327bde2017-11-23 17:03:20 +0100266 if (n + k > MAXPATHLEN) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000267 k = MAXPATHLEN - n;
Victor Stinner0327bde2017-11-23 17:03:20 +0100268 }
Martin v. Löwis790465f2008-04-05 20:41:37 +0000269 wcsncpy(buffer+n, stuff, k);
Fred Drakeedabdc12000-07-08 06:16:37 +0000270 buffer[n+k] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000271}
272
Victor Stinner0327bde2017-11-23 17:03:20 +0100273
Guido van Rossume296ced2001-09-28 20:00:29 +0000274/* copy_absolute requires that path be allocated at least
275 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000276static void
Victor Stinnerf4061da2010-10-14 12:37:19 +0000277copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000278{
Victor Stinner0327bde2017-11-23 17:03:20 +0100279 if (p[0] == SEP) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000280 wcscpy(path, p);
Victor Stinner0327bde2017-11-23 17:03:20 +0100281 }
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000282 else {
Victor Stinnerf4061da2010-10-14 12:37:19 +0000283 if (!_Py_wgetcwd(path, pathlen)) {
Victor Stinner4f3abb02010-10-07 23:29:18 +0000284 /* unable to get the current directory */
285 wcscpy(path, p);
286 return;
287 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100288 if (p[0] == '.' && p[1] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000289 p += 2;
Victor Stinner0327bde2017-11-23 17:03:20 +0100290 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000291 joinpath(path, p);
Jeremy Hylton7198ba92000-09-25 17:00:24 +0000292 }
293}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000294
Victor Stinner0327bde2017-11-23 17:03:20 +0100295
Guido van Rossume296ced2001-09-28 20:00:29 +0000296/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
297static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000298absolutize(wchar_t *path)
Guido van Rossume296ced2001-09-28 20:00:29 +0000299{
Victor Stinnerf4061da2010-10-14 12:37:19 +0000300 wchar_t buffer[MAXPATHLEN+1];
Guido van Rossume296ced2001-09-28 20:00:29 +0000301
Victor Stinner0327bde2017-11-23 17:03:20 +0100302 if (path[0] == SEP) {
Guido van Rossume296ced2001-09-28 20:00:29 +0000303 return;
Victor Stinner0327bde2017-11-23 17:03:20 +0100304 }
Victor Stinnerf4061da2010-10-14 12:37:19 +0000305 copy_absolute(buffer, path, MAXPATHLEN+1);
Martin v. Löwis790465f2008-04-05 20:41:37 +0000306 wcscpy(path, buffer);
Guido van Rossume296ced2001-09-28 20:00:29 +0000307}
308
Victor Stinner0327bde2017-11-23 17:03:20 +0100309
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100310/* search for a prefix value in an environment file. If found, copy it
311 to the provided buffer, which is expected to be no more than MAXPATHLEN
312 bytes long.
313*/
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100314static int
315find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
316{
317 int result = 0; /* meaning not found */
318 char buffer[MAXPATHLEN*2+1]; /* allow extra for key, '=', etc. */
319
320 fseek(env_file, 0, SEEK_SET);
321 while (!feof(env_file)) {
322 char * p = fgets(buffer, MAXPATHLEN*2, env_file);
323 wchar_t tmpbuffer[MAXPATHLEN*2+1];
324 PyObject * decoded;
325 int n;
326
Victor Stinner0327bde2017-11-23 17:03:20 +0100327 if (p == NULL) {
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100328 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100329 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100330 n = strlen(p);
331 if (p[n - 1] != '\n') {
332 /* line has overflowed - bail */
333 break;
334 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100335 if (p[0] == '#') {
336 /* Comment - skip */
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100337 continue;
Victor Stinner0327bde2017-11-23 17:03:20 +0100338 }
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100339 decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
340 if (decoded != NULL) {
341 Py_ssize_t k;
342 wchar_t * state;
343 k = PyUnicode_AsWideChar(decoded,
344 tmpbuffer, MAXPATHLEN * 2);
345 Py_DECREF(decoded);
346 if (k >= 0) {
347 wchar_t * tok = wcstok(tmpbuffer, L" \t\r\n", &state);
348 if ((tok != NULL) && !wcscmp(tok, key)) {
349 tok = wcstok(NULL, L" \t", &state);
350 if ((tok != NULL) && !wcscmp(tok, L"=")) {
351 tok = wcstok(NULL, L"\r\n", &state);
352 if (tok != NULL) {
353 wcsncpy(value, tok, MAXPATHLEN);
354 result = 1;
355 break;
356 }
357 }
358 }
359 }
360 }
361 }
362 return result;
363}
364
Victor Stinner0327bde2017-11-23 17:03:20 +0100365
Guido van Rossume296ced2001-09-28 20:00:29 +0000366/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000367 bytes long.
368*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000369static int
Victor Stinner9316ee42017-11-25 03:17:57 +0100370search_for_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000371{
Fred Drakeedabdc12000-07-08 06:16:37 +0000372 size_t n;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000373 wchar_t *vpath;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000374
Fred Drakeedabdc12000-07-08 06:16:37 +0000375 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinner0327bde2017-11-23 17:03:20 +0100376 if (calculate->home) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100377 wcsncpy(prefix, calculate->home, MAXPATHLEN);
378 prefix[MAXPATHLEN] = L'\0';
379 wchar_t *delim = wcschr(prefix, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100380 if (delim) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000381 *delim = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100382 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100383 joinpath(prefix, calculate->lib_python);
384 joinpath(prefix, LANDMARK);
Fred Drakeedabdc12000-07-08 06:16:37 +0000385 return 1;
386 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000387
Fred Drakeedabdc12000-07-08 06:16:37 +0000388 /* Check to see if argv[0] is in the build directory */
Victor Stinner9316ee42017-11-25 03:17:57 +0100389 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
390 prefix[MAXPATHLEN] = L'\0';
391 joinpath(prefix, L"Modules/Setup");
392 if (isfile(prefix)) {
Neil Schemenauer6cf07022001-01-24 17:13:11 +0000393 /* Check VPATH to see if argv0_path is in the build directory. */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200394 vpath = Py_DecodeLocale(VPATH, NULL);
Victor Stinner21582312010-10-23 00:13:28 +0000395 if (vpath != NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100396 wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
397 prefix[MAXPATHLEN] = L'\0';
398 joinpath(prefix, vpath);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200399 PyMem_RawFree(vpath);
Victor Stinner9316ee42017-11-25 03:17:57 +0100400 joinpath(prefix, L"Lib");
401 joinpath(prefix, LANDMARK);
402 if (ismodule(prefix)) {
Victor Stinner21582312010-10-23 00:13:28 +0000403 return -1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100404 }
Victor Stinner21582312010-10-23 00:13:28 +0000405 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000406 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000407
Fred Drakeedabdc12000-07-08 06:16:37 +0000408 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100409 copy_absolute(prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000410 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100411 n = wcslen(prefix);
412 joinpath(prefix, calculate->lib_python);
413 joinpath(prefix, LANDMARK);
414 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000415 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100416 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100417 prefix[n] = L'\0';
418 reduce(prefix);
419 } while (prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000420
Fred Drakeedabdc12000-07-08 06:16:37 +0000421 /* Look at configure's PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100422 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
423 prefix[MAXPATHLEN] = L'\0';
424 joinpath(prefix, calculate->lib_python);
425 joinpath(prefix, LANDMARK);
426 if (ismodule(prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000427 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100428 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000429
Fred Drakeedabdc12000-07-08 06:16:37 +0000430 /* Fail */
431 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000432}
433
434
Victor Stinner0327bde2017-11-23 17:03:20 +0100435static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100436calculate_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100437{
Victor Stinner9316ee42017-11-25 03:17:57 +0100438 calculate->prefix_found = search_for_prefix(calculate, prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100439 if (!calculate->prefix_found) {
440 if (!Py_FrozenFlag) {
441 fprintf(stderr,
442 "Could not find platform independent libraries <prefix>\n");
443 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100444 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
445 joinpath(prefix, calculate->lib_python);
Victor Stinner0327bde2017-11-23 17:03:20 +0100446 }
447 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100448 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100449 }
450}
451
452
453static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100454calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100455{
456 /* Reduce prefix and exec_prefix to their essence,
457 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
458 * If we're loading relative to the build directory,
459 * return the compiled-in defaults instead.
460 */
461 if (calculate->prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100462 reduce(prefix);
463 reduce(prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100464 /* The prefix is the root directory, but reduce() chopped
465 * off the "/". */
Victor Stinner9316ee42017-11-25 03:17:57 +0100466 if (!prefix[0]) {
467 wcscpy(prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100468 }
469 }
470 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100471 wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100472 }
473}
474
475
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000476/* search_for_exec_prefix requires that argv0_path be no more than
Guido van Rossume296ced2001-09-28 20:00:29 +0000477 MAXPATHLEN bytes long.
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000478*/
Guido van Rossum305e5d01997-04-11 17:18:45 +0000479static int
Victor Stinner9316ee42017-11-25 03:17:57 +0100480search_for_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Guido van Rossum305e5d01997-04-11 17:18:45 +0000481{
Fred Drakeedabdc12000-07-08 06:16:37 +0000482 size_t n;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000483
Fred Drakeedabdc12000-07-08 06:16:37 +0000484 /* If PYTHONHOME is set, we believe it unconditionally */
Victor Stinner0327bde2017-11-23 17:03:20 +0100485 if (calculate->home) {
486 wchar_t *delim = wcschr(calculate->home, DELIM);
487 if (delim) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100488 wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100489 }
490 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100491 wcsncpy(exec_prefix, calculate->home, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100492 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100493 exec_prefix[MAXPATHLEN] = L'\0';
494 joinpath(exec_prefix, calculate->lib_python);
495 joinpath(exec_prefix, L"lib-dynload");
Fred Drakeedabdc12000-07-08 06:16:37 +0000496 return 1;
497 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000498
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000499 /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
500 is written by setup.py and contains the relative path to the location
501 of shared library modules. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100502 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
503 exec_prefix[MAXPATHLEN] = L'\0';
504 joinpath(exec_prefix, L"pybuilddir.txt");
505 if (isfile(exec_prefix)) {
506 FILE *f = _Py_wfopen(exec_prefix, L"rb");
Victor Stinner0327bde2017-11-23 17:03:20 +0100507 if (f == NULL) {
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000508 errno = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100509 }
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000510 else {
511 char buf[MAXPATHLEN+1];
512 PyObject *decoded;
513 wchar_t rel_builddir_path[MAXPATHLEN+1];
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000514 n = fread(buf, 1, MAXPATHLEN, f);
515 buf[n] = '\0';
516 fclose(f);
517 decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
518 if (decoded != NULL) {
Victor Stinner47f637c2010-11-10 14:12:20 +0000519 Py_ssize_t k;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000520 k = PyUnicode_AsWideChar(decoded,
Victor Stinnere406ef42010-08-14 00:07:14 +0000521 rel_builddir_path, MAXPATHLEN);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000522 Py_DECREF(decoded);
Victor Stinner47f637c2010-11-10 14:12:20 +0000523 if (k >= 0) {
524 rel_builddir_path[k] = L'\0';
Victor Stinner9316ee42017-11-25 03:17:57 +0100525 wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
526 exec_prefix[MAXPATHLEN] = L'\0';
527 joinpath(exec_prefix, rel_builddir_path);
Antoine Pitroue9b428f2010-08-13 22:25:01 +0000528 return -1;
529 }
530 }
531 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000532 }
Jeremy Hylton847a9962000-05-26 21:49:07 +0000533
Fred Drakeedabdc12000-07-08 06:16:37 +0000534 /* Search from argv0_path, until root is found */
Victor Stinner9316ee42017-11-25 03:17:57 +0100535 copy_absolute(exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
Fred Drakeedabdc12000-07-08 06:16:37 +0000536 do {
Victor Stinner9316ee42017-11-25 03:17:57 +0100537 n = wcslen(exec_prefix);
538 joinpath(exec_prefix, calculate->lib_python);
539 joinpath(exec_prefix, L"lib-dynload");
540 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000541 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100542 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100543 exec_prefix[n] = L'\0';
544 reduce(exec_prefix);
545 } while (exec_prefix[0]);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000546
Fred Drakeedabdc12000-07-08 06:16:37 +0000547 /* Look at configure's EXEC_PREFIX */
Victor Stinner9316ee42017-11-25 03:17:57 +0100548 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
549 exec_prefix[MAXPATHLEN] = L'\0';
550 joinpath(exec_prefix, calculate->lib_python);
551 joinpath(exec_prefix, L"lib-dynload");
552 if (isdir(exec_prefix)) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000553 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100554 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000555
Fred Drakeedabdc12000-07-08 06:16:37 +0000556 /* Fail */
557 return 0;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000558}
559
Guido van Rossum305e5d01997-04-11 17:18:45 +0000560
Victor Stinner0327bde2017-11-23 17:03:20 +0100561static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100562calculate_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100563{
Victor Stinner9316ee42017-11-25 03:17:57 +0100564 calculate->exec_prefix_found = search_for_exec_prefix(calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100565 if (!calculate->exec_prefix_found) {
566 if (!Py_FrozenFlag) {
567 fprintf(stderr,
568 "Could not find platform dependent libraries <exec_prefix>\n");
569 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100570 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
571 joinpath(exec_prefix, L"lib/lib-dynload");
Victor Stinner0327bde2017-11-23 17:03:20 +0100572 }
573 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
574}
575
576
577static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100578calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100579{
580 if (calculate->exec_prefix_found > 0) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100581 reduce(exec_prefix);
582 reduce(exec_prefix);
583 reduce(exec_prefix);
584 if (!exec_prefix[0]) {
585 wcscpy(exec_prefix, separator);
Victor Stinner0327bde2017-11-23 17:03:20 +0100586 }
587 }
588 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100589 wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100590 }
591}
592
593
Victor Stinner9316ee42017-11-25 03:17:57 +0100594static _PyInitError
595calculate_program_name(PyCalculatePath *calculate, PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100596{
Victor Stinner9316ee42017-11-25 03:17:57 +0100597 wchar_t program_name[MAXPATHLEN+1];
598 memset(program_name, 0, sizeof(program_name));
599
Victor Stinnerb9197952017-11-23 19:02:04 +0100600#ifdef __APPLE__
601#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
602 uint32_t nsexeclength = MAXPATHLEN;
603#else
604 unsigned long nsexeclength = MAXPATHLEN;
605#endif
606 char execpath[MAXPATHLEN+1];
607#endif
608
Victor Stinner0327bde2017-11-23 17:03:20 +0100609 /* If there is no slash in the argv0 path, then we have to
610 * assume python is on the user's $PATH, since there's no
611 * other way to find a directory to start the search from. If
612 * $PATH isn't exported, you lose.
613 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100614 if (wcschr(calculate->program_name, SEP)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100615 wcsncpy(program_name, calculate->program_name, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100616 }
Jack Jansen1afd4802004-06-03 14:33:03 +0000617#ifdef __APPLE__
Jack Jansen1afd4802004-06-03 14:33:03 +0000618 /* On Mac OS X, if a script uses an interpreter of the form
619 * "#!/opt/python2.3/bin/python", the kernel only passes "python"
620 * as argv[0], which falls through to the $PATH search below.
621 * If /opt/python2.3/bin isn't in your path, or is near the end,
622 * this algorithm may incorrectly find /usr/bin/python. To work
623 * around this, we can use _NSGetExecutablePath to get a better
624 * hint of what the intended interpreter was, although this
625 * will fail if a relative path was used. but in that case,
626 * absolutize() should help us out below
627 */
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100628 else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
629 execpath[0] == SEP)
630 {
Victor Stinner9316ee42017-11-25 03:17:57 +0100631 size_t r = mbstowcs(program_name, execpath, MAXPATHLEN+1);
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000632 if (r == (size_t)-1 || r > MAXPATHLEN) {
633 /* Could not convert execpath, or it's too long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100634 program_name[0] = '\0';
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000636 }
Brett Cannon6cc48142004-06-24 00:48:44 +0000637#endif /* __APPLE__ */
Victor Stinner0327bde2017-11-23 17:03:20 +0100638 else if (calculate->path_env) {
639 wchar_t *path = calculate->path_env;
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000640 while (1) {
641 wchar_t *delim = wcschr(path, DELIM);
Jack Jansen55070f52001-12-02 23:56:28 +0000642
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000643 if (delim) {
644 size_t len = delim - path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100645 if (len > MAXPATHLEN) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000646 len = MAXPATHLEN;
Victor Stinner0327bde2017-11-23 17:03:20 +0100647 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100648 wcsncpy(program_name, path, len);
649 program_name[len] = '\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000650 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100651 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100652 wcsncpy(program_name, path, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100653 }
Jack Jansen55070f52001-12-02 23:56:28 +0000654
Victor Stinner9316ee42017-11-25 03:17:57 +0100655 joinpath(program_name, calculate->program_name);
656 if (isxfile(program_name)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000657 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100658 }
Jack Jansen55070f52001-12-02 23:56:28 +0000659
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000660 if (!delim) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100661 program_name[0] = L'\0';
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000662 break;
663 }
664 path = delim + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 }
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000666 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100667 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100668 program_name[0] = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100669 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100670 if (program_name[0] != SEP && program_name[0] != '\0') {
671 absolutize(program_name);
Victor Stinner0327bde2017-11-23 17:03:20 +0100672 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100673
674 config->program_name = _PyMem_RawWcsdup(program_name);
675 if (config->program_name == NULL) {
676 return _Py_INIT_NO_MEMORY();
677 }
678 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100679}
680
681
Victor Stinner9316ee42017-11-25 03:17:57 +0100682static _PyInitError
683calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_name)
Victor Stinner0327bde2017-11-23 17:03:20 +0100684{
Victor Stinner9316ee42017-11-25 03:17:57 +0100685 wcsncpy(calculate->argv0_path, program_name, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100686 calculate->argv0_path[MAXPATHLEN] = '\0';
Jack Jansen55070f52001-12-02 23:56:28 +0000687
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000688#ifdef WITH_NEXT_FRAMEWORK
Victor Stinner0327bde2017-11-23 17:03:20 +0100689 NSModule pythonModule;
690
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000691 /* On Mac OS X we have a special case if we're running from a framework.
692 ** This is because the python home should be set relative to the library,
693 ** which is in the framework, not relative to the executable, which may
694 ** be outside of the framework. Except when we're in the build directory...
695 */
Fred Drakeedabdc12000-07-08 06:16:37 +0000696 pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
697 /* Use dylib functions to find out where the framework was loaded from */
Victor Stinner0327bde2017-11-23 17:03:20 +0100698 const char* modPath = NSLibraryNameForModule(pythonModule);
Vinay Sajip90db6612012-07-17 17:33:46 +0100699 if (modPath != NULL) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000700 /* We're in a framework. */
Jack Jansene925faf2001-08-15 01:14:40 +0000701 /* See if we might be in the build directory. The framework in the
702 ** build directory is incomplete, it only has the .dylib and a few
703 ** needed symlinks, it doesn't have the Lib directories and such.
704 ** If we're running with the framework from the build directory we must
705 ** be running the interpreter in the build directory, so we use the
706 ** build-directory-specific logic to find Lib and such.
707 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100708 size_t len;
709 wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100710 if (wbuf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100711 return DECODE_LOCALE_ERR("framework location", len);
Vinay Sajip90db6612012-07-17 17:33:46 +0100712 }
713
Victor Stinner0327bde2017-11-23 17:03:20 +0100714 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
715 reduce(calculate->argv0_path);
716 joinpath(calculate->argv0_path, calculate->lib_python);
717 joinpath(calculate->argv0_path, LANDMARK);
718 if (!ismodule(calculate->argv0_path)) {
Antoine Pitrou99773ac2010-08-14 12:34:41 +0000719 /* We are in the build directory so use the name of the
720 executable - we know that the absolute path is passed */
Victor Stinner9316ee42017-11-25 03:17:57 +0100721 wcsncpy(calculate->argv0_path, program_name, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000722 }
723 else {
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100724 /* Use the location of the library as the program_name */
Victor Stinner0327bde2017-11-23 17:03:20 +0100725 wcsncpy(calculate->argv0_path, wbuf, MAXPATHLEN);
Jack Jansene925faf2001-08-15 01:14:40 +0000726 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200727 PyMem_RawFree(wbuf);
Fred Drakeedabdc12000-07-08 06:16:37 +0000728 }
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000729#endif
Guido van Rossume296ced2001-09-28 20:00:29 +0000730
Guido van Rossum305e5d01997-04-11 17:18:45 +0000731#if HAVE_READLINK
Victor Stinner0327bde2017-11-23 17:03:20 +0100732 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinner9316ee42017-11-25 03:17:57 +0100733 int linklen = _Py_wreadlink(program_name, tmpbuffer, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100734 while (linklen != -1) {
735 if (tmpbuffer[0] == SEP) {
736 /* tmpbuffer should never be longer than MAXPATHLEN,
737 but extra check does not hurt */
738 wcsncpy(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000739 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100740 else {
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100741 /* Interpret relative to program_name */
Victor Stinner0327bde2017-11-23 17:03:20 +0100742 reduce(calculate->argv0_path);
743 joinpath(calculate->argv0_path, tmpbuffer);
744 }
745 linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, MAXPATHLEN);
Fred Drakeedabdc12000-07-08 06:16:37 +0000746 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000747#endif /* HAVE_READLINK */
748
Victor Stinner0327bde2017-11-23 17:03:20 +0100749 reduce(calculate->argv0_path);
Jeremy Hylton6372fe12000-09-27 20:51:17 +0000750 /* At this point, argv0_path is guaranteed to be less than
Victor Stinner0327bde2017-11-23 17:03:20 +0100751 MAXPATHLEN bytes long. */
Victor Stinner9316ee42017-11-25 03:17:57 +0100752 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100753}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000754
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100755
Victor Stinner0327bde2017-11-23 17:03:20 +0100756/* Search for an "pyvenv.cfg" environment configuration file, first in the
757 executable's directory and then in the parent directory.
758 If found, open it for use when searching for prefixes.
759*/
760static void
761calculate_read_pyenv(PyCalculatePath *calculate)
762{
763 wchar_t tmpbuffer[MAXPATHLEN+1];
764 wchar_t *env_cfg = L"pyvenv.cfg";
765 FILE *env_file;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100766
Victor Stinner0327bde2017-11-23 17:03:20 +0100767 wcscpy(tmpbuffer, calculate->argv0_path);
Vinay Sajip90db6612012-07-17 17:33:46 +0100768
Victor Stinner0327bde2017-11-23 17:03:20 +0100769 joinpath(tmpbuffer, env_cfg);
770 env_file = _Py_wfopen(tmpbuffer, L"r");
771 if (env_file == NULL) {
772 errno = 0;
773
774 reduce(tmpbuffer);
775 reduce(tmpbuffer);
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100776 joinpath(tmpbuffer, env_cfg);
Victor Stinner0327bde2017-11-23 17:03:20 +0100777
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100778 env_file = _Py_wfopen(tmpbuffer, L"r");
779 if (env_file == NULL) {
780 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100781 }
782 }
783
Victor Stinner0327bde2017-11-23 17:03:20 +0100784 if (env_file == NULL) {
785 return;
Fred Drakeedabdc12000-07-08 06:16:37 +0000786 }
Guido van Rossume296ced2001-09-28 20:00:29 +0000787
Victor Stinner0327bde2017-11-23 17:03:20 +0100788 /* Look for a 'home' variable and set argv0_path to it, if found */
789 if (find_env_config_value(env_file, L"home", tmpbuffer)) {
790 wcscpy(calculate->argv0_path, tmpbuffer);
Just van Rossum52e14d62002-12-30 22:08:05 +0000791 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100792 fclose(env_file);
793}
Just van Rossum52e14d62002-12-30 22:08:05 +0000794
Guido van Rossum305e5d01997-04-11 17:18:45 +0000795
Victor Stinner0327bde2017-11-23 17:03:20 +0100796static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100797calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100798{
Victor Stinner9316ee42017-11-25 03:17:57 +0100799 wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
Victor Stinner0327bde2017-11-23 17:03:20 +0100800 calculate->zip_path[MAXPATHLEN] = L'\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000801
Victor Stinner0327bde2017-11-23 17:03:20 +0100802 if (calculate->prefix_found > 0) {
803 /* Use the reduced prefix returned by Py_GetPrefix() */
804 reduce(calculate->zip_path);
805 reduce(calculate->zip_path);
Victor Stinnerd4341102017-11-23 00:12:09 +0100806 }
807 else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100808 wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
809 }
810 joinpath(calculate->zip_path, L"lib/python00.zip");
811
812 /* Replace "00" with version */
813 size_t bufsz = wcslen(calculate->zip_path);
814 calculate->zip_path[bufsz - 6] = VERSION[0];
815 calculate->zip_path[bufsz - 5] = VERSION[2];
816}
817
818
Victor Stinner9316ee42017-11-25 03:17:57 +0100819static _PyInitError
820calculate_module_search_path(PyCalculatePath *calculate,
821 const wchar_t *prefix, const wchar_t *exec_prefix,
822 PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +0100823{
824 /* Calculate size of return buffer */
825 size_t bufsz = 0;
826 if (calculate->module_search_path_env != NULL) {
827 bufsz += wcslen(calculate->module_search_path_env) + 1;
Martin v. Löwis790465f2008-04-05 20:41:37 +0000828 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000829
Victor Stinner0327bde2017-11-23 17:03:20 +0100830 wchar_t *defpath = calculate->pythonpath;
Victor Stinner9316ee42017-11-25 03:17:57 +0100831 size_t prefixsz = wcslen(prefix) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000832 while (1) {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000833 wchar_t *delim = wcschr(defpath, DELIM);
Guido van Rossum305e5d01997-04-11 17:18:45 +0000834
Victor Stinner0327bde2017-11-23 17:03:20 +0100835 if (defpath[0] != SEP) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000836 /* Paths are relative to prefix */
837 bufsz += prefixsz;
Victor Stinner0327bde2017-11-23 17:03:20 +0100838 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000839
Victor Stinner0327bde2017-11-23 17:03:20 +0100840 if (delim) {
Fred Drakeedabdc12000-07-08 06:16:37 +0000841 bufsz += delim - defpath + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100842 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000843 else {
Martin v. Löwis790465f2008-04-05 20:41:37 +0000844 bufsz += wcslen(defpath) + 1;
Fred Drakeedabdc12000-07-08 06:16:37 +0000845 break;
846 }
847 defpath = delim + 1;
848 }
Guido van Rossum305e5d01997-04-11 17:18:45 +0000849
Victor Stinner0327bde2017-11-23 17:03:20 +0100850 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner9316ee42017-11-25 03:17:57 +0100851 bufsz += wcslen(exec_prefix) + 1;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000852
Victor Stinner0327bde2017-11-23 17:03:20 +0100853 /* Allocate the buffer */
854 wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Fred Drakeedabdc12000-07-08 06:16:37 +0000855 if (buf == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100856 return _Py_INIT_NO_MEMORY();
Fred Drakeedabdc12000-07-08 06:16:37 +0000857 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100858 buf[0] = '\0';
Guido van Rossum305e5d01997-04-11 17:18:45 +0000859
Victor Stinner72967a42013-11-16 01:22:04 +0100860 /* Run-time value of $PYTHONPATH goes first */
Victor Stinner0327bde2017-11-23 17:03:20 +0100861 if (calculate->module_search_path_env) {
862 wcscpy(buf, calculate->module_search_path_env);
863 wcscat(buf, delimiter);
Fred Drakeedabdc12000-07-08 06:16:37 +0000864 }
Victor Stinner72967a42013-11-16 01:22:04 +0100865
866 /* Next is the default zip path */
Victor Stinner0327bde2017-11-23 17:03:20 +0100867 wcscat(buf, calculate->zip_path);
Victor Stinner72967a42013-11-16 01:22:04 +0100868 wcscat(buf, delimiter);
869
870 /* Next goes merge of compile-time $PYTHONPATH with
871 * dynamically located prefix.
872 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100873 defpath = calculate->pythonpath;
Victor Stinner72967a42013-11-16 01:22:04 +0100874 while (1) {
875 wchar_t *delim = wcschr(defpath, DELIM);
876
877 if (defpath[0] != SEP) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100878 wcscat(buf, prefix);
879 if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
Victor Stinner0327bde2017-11-23 17:03:20 +0100880 defpath[0] != (delim ? DELIM : L'\0'))
881 {
882 /* not empty */
Serhiy Storchaka62e32d62016-11-11 12:05:01 +0200883 wcscat(buf, separator);
884 }
Victor Stinner72967a42013-11-16 01:22:04 +0100885 }
886
887 if (delim) {
888 size_t len = delim - defpath + 1;
889 size_t end = wcslen(buf) + len;
890 wcsncat(buf, defpath, len);
Victor Stinner9316ee42017-11-25 03:17:57 +0100891 buf[end] = '\0';
Victor Stinner72967a42013-11-16 01:22:04 +0100892 }
893 else {
894 wcscat(buf, defpath);
895 break;
896 }
897 defpath = delim + 1;
898 }
899 wcscat(buf, delimiter);
900
901 /* Finally, on goes the directory for dynamic-load modules */
Victor Stinner9316ee42017-11-25 03:17:57 +0100902 wcscat(buf, exec_prefix);
Victor Stinner72967a42013-11-16 01:22:04 +0100903
Victor Stinner9316ee42017-11-25 03:17:57 +0100904 config->module_search_path = buf;
905 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100906}
Guido van Rossum305e5d01997-04-11 17:18:45 +0000907
Victor Stinner0327bde2017-11-23 17:03:20 +0100908
Victor Stinner0327bde2017-11-23 17:03:20 +0100909static _PyInitError
910calculate_init(PyCalculatePath *calculate,
911 const _PyMainInterpreterConfig *main_config)
912{
Victor Stinner46972b72017-11-24 22:55:40 +0100913 calculate->home = main_config->home;
914 calculate->module_search_path_env = main_config->module_search_path_env;
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100915 calculate->program_name = main_config->program_name;
Guido van Rossum305e5d01997-04-11 17:18:45 +0000916
Victor Stinner0327bde2017-11-23 17:03:20 +0100917 size_t len;
918 char *path = getenv("PATH");
919 if (path) {
920 calculate->path_env = Py_DecodeLocale(path, &len);
921 if (!calculate->path_env) {
Victor Stinner46972b72017-11-24 22:55:40 +0100922 return DECODE_LOCALE_ERR("PATH environment variable", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100923 }
Fred Drakeedabdc12000-07-08 06:16:37 +0000924 }
Victor Stinnerae4836d2010-11-08 23:49:47 +0000925
Victor Stinner0327bde2017-11-23 17:03:20 +0100926 calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len);
927 if (!calculate->pythonpath) {
Victor Stinner46972b72017-11-24 22:55:40 +0100928 return DECODE_LOCALE_ERR("PYTHONPATH define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100929 }
930 calculate->prefix = Py_DecodeLocale(PREFIX, &len);
931 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100932 return DECODE_LOCALE_ERR("PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100933 }
934 calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
935 if (!calculate->prefix) {
Victor Stinner46972b72017-11-24 22:55:40 +0100936 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100937 }
938 calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
939 if (!calculate->lib_python) {
Victor Stinner46972b72017-11-24 22:55:40 +0100940 return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
Victor Stinner0327bde2017-11-23 17:03:20 +0100941 }
942 return _Py_INIT_OK();
943}
944
945
946static void
947calculate_free(PyCalculatePath *calculate)
948{
949 PyMem_RawFree(calculate->pythonpath);
950 PyMem_RawFree(calculate->prefix);
951 PyMem_RawFree(calculate->exec_prefix);
952 PyMem_RawFree(calculate->lib_python);
953 PyMem_RawFree(calculate->path_env);
Victor Stinner0327bde2017-11-23 17:03:20 +0100954}
955
956
Victor Stinner9316ee42017-11-25 03:17:57 +0100957static _PyInitError
Victor Stinner0327bde2017-11-23 17:03:20 +0100958calculate_path_impl(PyCalculatePath *calculate, PyPathConfig *config)
959{
Victor Stinner9316ee42017-11-25 03:17:57 +0100960 _PyInitError err = calculate_program_name(calculate, config);
961 if (_Py_INIT_FAILED(err)) {
962 return err;
963 }
964
965 err = calculate_argv0_path(calculate, config->program_name);
966 if (_Py_INIT_FAILED(err)) {
967 return err;
968 }
969
Victor Stinner0327bde2017-11-23 17:03:20 +0100970 calculate_read_pyenv(calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +0100971
972 wchar_t prefix[MAXPATHLEN+1];
973 memset(prefix, 0, sizeof(prefix));
974 calculate_prefix(calculate, prefix);
975
976 calculate_zip_path(calculate, prefix);
977
978 wchar_t exec_prefix[MAXPATHLEN+1];
979 memset(exec_prefix, 0, sizeof(exec_prefix));
980 calculate_exec_prefix(calculate, exec_prefix);
Victor Stinner0327bde2017-11-23 17:03:20 +0100981
Victor Stinnerf04ebe22017-11-25 00:01:23 +0100982 if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
983 !Py_FrozenFlag)
984 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100985 fprintf(stderr,
986 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
987 }
988
Victor Stinner9316ee42017-11-25 03:17:57 +0100989 err = calculate_module_search_path(calculate, prefix, exec_prefix,
990 config);
991 if (_Py_INIT_FAILED(err)) {
992 return err;
993 }
994
995 calculate_reduce_prefix(calculate, prefix);
996
997 config->prefix = _PyMem_RawWcsdup(prefix);
998 if (config->prefix == NULL) {
999 return _Py_INIT_NO_MEMORY();
1000 }
1001
1002 calculate_reduce_exec_prefix(calculate, exec_prefix);
1003
1004 config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
1005 if (config->exec_prefix == NULL) {
1006 return _Py_INIT_NO_MEMORY();
1007 }
1008
1009 return _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001010}
1011
1012
1013static void
Victor Stinner9316ee42017-11-25 03:17:57 +01001014pathconfig_clear(PyPathConfig *config)
Victor Stinner0327bde2017-11-23 17:03:20 +01001015{
Victor Stinner9316ee42017-11-25 03:17:57 +01001016#define CLEAR(ATTR) \
1017 do { \
1018 PyMem_RawFree(ATTR); \
1019 ATTR = NULL; \
1020 } while (0)
1021
1022 CLEAR(config->prefix);
1023 CLEAR(config->exec_prefix);
1024 CLEAR(config->program_name);
1025 CLEAR(config->module_search_path);
1026#undef CLEAR
1027}
1028
1029
1030/* Initialize paths for Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix()
1031 and Py_GetProgramFullPath() */
1032_PyInitError
1033_PyPathConfig_Init(const _PyMainInterpreterConfig *main_config)
1034{
1035 if (path_config.module_search_path) {
1036 /* Already initialized */
1037 return _Py_INIT_OK();
1038 }
1039
Victor Stinner0327bde2017-11-23 17:03:20 +01001040 PyCalculatePath calculate;
1041 memset(&calculate, 0, sizeof(calculate));
1042
Victor Stinner9316ee42017-11-25 03:17:57 +01001043 _PyInitError err = calculate_init(&calculate, main_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001044 if (_Py_INIT_FAILED(err)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001045 goto done;
Victor Stinner0327bde2017-11-23 17:03:20 +01001046 }
1047
1048 PyPathConfig new_path_config;
1049 memset(&new_path_config, 0, sizeof(new_path_config));
1050
Victor Stinner9316ee42017-11-25 03:17:57 +01001051 err = calculate_path_impl(&calculate, &new_path_config);
1052 if (_Py_INIT_FAILED(err)) {
1053 pathconfig_clear(&new_path_config);
1054 goto done;
1055 }
1056
Victor Stinner0327bde2017-11-23 17:03:20 +01001057 path_config = new_path_config;
Victor Stinner9316ee42017-11-25 03:17:57 +01001058 err = _Py_INIT_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +01001059
Victor Stinner9316ee42017-11-25 03:17:57 +01001060done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001061 calculate_free(&calculate);
Victor Stinner9316ee42017-11-25 03:17:57 +01001062 return err;
1063}
Victor Stinner46972b72017-11-24 22:55:40 +01001064
Victor Stinner9316ee42017-11-25 03:17:57 +01001065
1066static void
1067calculate_path(void)
1068{
1069 _PyInitError err;
1070 _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
1071
1072 err = _PyMainInterpreterConfig_ReadEnv(&config);
1073 if (!_Py_INIT_FAILED(err)) {
1074 err = _PyPathConfig_Init(&config);
Victor Stinner46972b72017-11-24 22:55:40 +01001075 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001076 _PyMainInterpreterConfig_Clear(&config);
1077
1078 if (_Py_INIT_FAILED(err)) {
1079 _Py_FatalInitError(err);
1080 }
1081}
1082
1083
1084void
1085_PyPathConfig_Fini(void)
1086{
1087 pathconfig_clear(&path_config);
Guido van Rossum305e5d01997-04-11 17:18:45 +00001088}
1089
1090
1091/* External interface */
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +00001092void
1093Py_SetPath(const wchar_t *path)
1094{
Victor Stinner0327bde2017-11-23 17:03:20 +01001095 if (path == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001096 pathconfig_clear(&path_config);
Victor Stinner0327bde2017-11-23 17:03:20 +01001097 return;
1098 }
1099
Victor Stinner9316ee42017-11-25 03:17:57 +01001100 PyPathConfig new_config;
1101 new_config.program_name = _PyMem_RawWcsdup(Py_GetProgramName());
1102 new_config.exec_prefix = _PyMem_RawWcsdup(L"");
1103 new_config.prefix = _PyMem_RawWcsdup(L"");
1104 new_config.module_search_path = _PyMem_RawWcsdup(path);
Guido van Rossum667d7041995-08-04 04:20:48 +00001105
Victor Stinner9316ee42017-11-25 03:17:57 +01001106 pathconfig_clear(&path_config);
1107 path_config = new_config;
Victor Stinnerd4341102017-11-23 00:12:09 +01001108}
1109
Victor Stinner0327bde2017-11-23 17:03:20 +01001110
Victor Stinnerd4341102017-11-23 00:12:09 +01001111wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001112Py_GetPath(void)
Guido van Rossum667d7041995-08-04 04:20:48 +00001113{
Victor Stinner0327bde2017-11-23 17:03:20 +01001114 if (!path_config.module_search_path) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001115 calculate_path();
Victor Stinner0327bde2017-11-23 17:03:20 +01001116 }
1117 return path_config.module_search_path;
Guido van Rossum667d7041995-08-04 04:20:48 +00001118}
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001119
Victor Stinner0327bde2017-11-23 17:03:20 +01001120
Martin v. Löwis790465f2008-04-05 20:41:37 +00001121wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001122Py_GetPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001123{
Victor Stinner0327bde2017-11-23 17:03:20 +01001124 if (!path_config.module_search_path) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001125 calculate_path();
Victor Stinner0327bde2017-11-23 17:03:20 +01001126 }
1127 return path_config.prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001128}
1129
Victor Stinner0327bde2017-11-23 17:03:20 +01001130
Martin v. Löwis790465f2008-04-05 20:41:37 +00001131wchar_t *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001132Py_GetExecPrefix(void)
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001133{
Victor Stinner0327bde2017-11-23 17:03:20 +01001134 if (!path_config.module_search_path) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001135 calculate_path();
Victor Stinner0327bde2017-11-23 17:03:20 +01001136 }
1137 return path_config.exec_prefix;
Guido van Rossumc34c9a51996-06-12 04:20:27 +00001138}
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001139
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_GetProgramFullPath(void)
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001143{
Victor Stinner0327bde2017-11-23 17:03:20 +01001144 if (!path_config.module_search_path) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001145 calculate_path();
Victor Stinner0327bde2017-11-23 17:03:20 +01001146 }
Victor Stinnerf04ebe22017-11-25 00:01:23 +01001147 return path_config.program_name;
Guido van Rossum7929c6f1997-05-20 22:38:21 +00001148}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001149
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001150#ifdef __cplusplus
1151}
1152#endif