blob: daa222703697dfbac7d1c9df31010c64d85a0698 [file] [log] [blame]
Victor Stinner0ea395a2017-12-01 20:50:58 +01001/* Path configuration like module_search_path (sys.path) */
2
3#include "Python.h"
4#include "osdefs.h"
5#include "internal/pystate.h"
6
7#ifdef __cplusplus
8extern "C" {
9#endif
10
11
12_PyPathConfig _Py_path_config = _PyPathConfig_INIT;
13#ifdef MS_WINDOWS
14static wchar_t *progname = L"python";
15#else
16static wchar_t *progname = L"python3";
17#endif
18static wchar_t *default_home = NULL;
19
20
21void
22_PyPathConfig_Clear(_PyPathConfig *config)
23{
24#define CLEAR(ATTR) \
25 do { \
26 PyMem_RawFree(ATTR); \
27 ATTR = NULL; \
28 } while (0)
29
30 CLEAR(config->prefix);
31 CLEAR(config->program_full_path);
32#ifdef MS_WINDOWS
33 CLEAR(config->dll_path);
34#else
35 CLEAR(config->exec_prefix);
36#endif
37 CLEAR(config->module_search_path);
38#undef CLEAR
39}
40
41
42void
43Py_SetProgramName(wchar_t *pn)
44{
45 if (pn && *pn)
46 progname = pn;
47}
48
49
50wchar_t *
51Py_GetProgramName(void)
52{
53 return progname;
54}
55
56
57void
58Py_SetPythonHome(wchar_t *home)
59{
60 default_home = home;
61}
62
63
64wchar_t*
65Py_GetPythonHome(void)
66{
67 /* Use a static buffer to avoid heap memory allocation failure.
68 Py_GetPythonHome() doesn't allow to report error, and the caller
69 doesn't release memory. */
70 static wchar_t buffer[MAXPATHLEN+1];
71
72 if (default_home) {
73 return default_home;
74 }
75
76 char *home = Py_GETENV("PYTHONHOME");
77 if (!home) {
78 return NULL;
79 }
80
81 size_t size = Py_ARRAY_LENGTH(buffer);
82 size_t r = mbstowcs(buffer, home, size);
83 if (r == (size_t)-1 || r >= size) {
84 /* conversion failed or the static buffer is too small */
85 return NULL;
86 }
87
88 return buffer;
89}
90
91
92static void
93pathconfig_global_init(void)
94{
95 if (_Py_path_config.module_search_path) {
96 /* Already initialized */
97 return;
98 }
99
100 _PyInitError err;
101 _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
102
103 err = _PyMainInterpreterConfig_ReadEnv(&config);
104 if (_Py_INIT_FAILED(err)) {
105 goto error;
106 }
107
108 err = _PyMainInterpreterConfig_Read(&config);
109 if (_Py_INIT_FAILED(err)) {
110 goto error;
111 }
112
113 err = _PyPathConfig_Init(&config);
114 if (_Py_INIT_FAILED(err)) {
115 goto error;
116 }
117
118 _PyMainInterpreterConfig_Clear(&config);
119 return;
120
121error:
122 _PyMainInterpreterConfig_Clear(&config);
123 _Py_FatalInitError(err);
124}
125
126
127/* External interface */
128
129void
130Py_SetPath(const wchar_t *path)
131{
132 if (path == NULL) {
133 _PyPathConfig_Clear(&_Py_path_config);
134 return;
135 }
136
137 _PyPathConfig new_config;
138 new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
139 new_config.prefix = _PyMem_RawWcsdup(L"");
140#ifdef MS_WINDOWS
141 new_config.dll_path = _PyMem_RawWcsdup(L"");
142#else
143 new_config.exec_prefix = _PyMem_RawWcsdup(L"");
144#endif
145 new_config.module_search_path = _PyMem_RawWcsdup(path);
146
147 _PyPathConfig_Clear(&_Py_path_config);
148 _Py_path_config = new_config;
149}
150
151
152wchar_t *
153Py_GetPath(void)
154{
155 pathconfig_global_init();
156 return _Py_path_config.module_search_path;
157}
158
159
160wchar_t *
161Py_GetPrefix(void)
162{
163 pathconfig_global_init();
164 return _Py_path_config.prefix;
165}
166
167
168wchar_t *
169Py_GetExecPrefix(void)
170{
171#ifdef MS_WINDOWS
172 return Py_GetPrefix();
173#else
174 pathconfig_global_init();
175 return _Py_path_config.exec_prefix;
176#endif
177}
178
179
180wchar_t *
181Py_GetProgramFullPath(void)
182{
183 pathconfig_global_init();
184 return _Py_path_config.program_full_path;
185}
186
187#ifdef __cplusplus
188}
189#endif