| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | /* Path configuration like module_search_path (sys.path) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2020-04-15 03:24:57 +02:00
										 |  |  | #include "osdefs.h"               // DELIM
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | #include "pycore_initconfig.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-07 00:44:03 +01:00
										 |  |  | #include "pycore_fileutils.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-01 03:15:58 +01:00
										 |  |  | #include "pycore_pathconfig.h"
 | 
					
						
							| 
									
										
										
										
											2020-04-15 02:57:50 +02:00
										 |  |  | #include "pycore_pymem.h"         // _PyMem_SetDefaultAllocator()
 | 
					
						
							| 
									
										
										
										
											2018-03-25 23:03:10 +10:00
										 |  |  | #include <wchar.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-14 17:52:15 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | #  include <windows.h>            // GetFullPathNameW(), MAX_PATH
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _PyPathConfig _Py_path_config = _PyPathConfig_INIT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | static int | 
					
						
							|  |  |  | copy_wstr(wchar_t **dst, const wchar_t *src) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-24 17:44:15 +02:00
										 |  |  |     assert(*dst == NULL); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |     if (src != NULL) { | 
					
						
							|  |  |  |         *dst = _PyMem_RawWcsdup(src); | 
					
						
							|  |  |  |         if (*dst == NULL) { | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         *dst = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | pathconfig_clear(_PyPathConfig *config) | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator,
 | 
					
						
							|  |  |  |        since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be | 
					
						
							|  |  |  |        called before Py_Initialize() which can changes the memory allocator. */ | 
					
						
							|  |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CLEAR(ATTR) \
 | 
					
						
							|  |  |  |     do { \ | 
					
						
							|  |  |  |         PyMem_RawFree(ATTR); \ | 
					
						
							|  |  |  |         ATTR = NULL; \ | 
					
						
							|  |  |  |     } while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CLEAR(config->program_full_path); | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     CLEAR(config->prefix); | 
					
						
							| 
									
										
										
										
											2018-11-17 20:41:48 -08:00
										 |  |  |     CLEAR(config->exec_prefix); | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  |     CLEAR(config->module_search_path); | 
					
						
							|  |  |  |     CLEAR(config->program_name); | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     CLEAR(config->home); | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2019-06-29 10:34:11 -07:00
										 |  |  |     CLEAR(config->base_executable); | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | #undef CLEAR
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2) | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     pathconfig_clear(config); | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | #define COPY_ATTR(ATTR) \
 | 
					
						
							|  |  |  |     do { \ | 
					
						
							|  |  |  |         if (copy_wstr(&config->ATTR, config2->ATTR) < 0) { \ | 
					
						
							|  |  |  |             return _PyStatus_NO_MEMORY(); \ | 
					
						
							|  |  |  |         } \ | 
					
						
							|  |  |  |     } while (0) | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     COPY_ATTR(program_full_path); | 
					
						
							|  |  |  |     COPY_ATTR(prefix); | 
					
						
							|  |  |  |     COPY_ATTR(exec_prefix); | 
					
						
							|  |  |  |     COPY_ATTR(module_search_path); | 
					
						
							|  |  |  |     COPY_ATTR(program_name); | 
					
						
							|  |  |  |     COPY_ATTR(home); | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     config->isolated = config2->isolated; | 
					
						
							|  |  |  |     config->site_import = config2->site_import; | 
					
						
							|  |  |  |     COPY_ATTR(base_executable); | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | #undef COPY_ATTR
 | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | _PyPathConfig_ClearGlobal(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-18 22:24:28 +01:00
										 |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     pathconfig_clear(&_Py_path_config); | 
					
						
							| 
									
										
										
										
											2019-03-18 22:24:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static wchar_t* | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep) | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     size_t len = 1;   /* NUL terminator */ | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |     for (Py_ssize_t i=0; i < list->length; i++) { | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         if (i != 0) { | 
					
						
							|  |  |  |             len++; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |         len += wcslen(list->items[i]); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t)); | 
					
						
							|  |  |  |     if (text == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     wchar_t *str = text; | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  |     for (Py_ssize_t i=0; i < list->length; i++) { | 
					
						
							|  |  |  |         wchar_t *path = list->items[i]; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         if (i != 0) { | 
					
						
							| 
									
										
										
										
											2019-09-26 15:51:50 +02:00
										 |  |  |             *str++ = sep; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         len = wcslen(path); | 
					
						
							|  |  |  |         memcpy(str, path, len * sizeof(wchar_t)); | 
					
						
							|  |  |  |         str += len; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     *str = L'\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return text; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-21 01:02:56 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config) | 
					
						
							| 
									
										
										
										
											2019-09-21 01:02:56 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2019-09-21 01:02:56 +02:00
										 |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     if (config->module_search_paths_set) { | 
					
						
							| 
									
										
										
										
											2019-09-24 17:44:15 +02:00
										 |  |  |         PyMem_RawFree(pathconfig->module_search_path); | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |         pathconfig->module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM); | 
					
						
							|  |  |  |         if (pathconfig->module_search_path == NULL) { | 
					
						
							|  |  |  |             goto no_memory; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | #define COPY_CONFIG(PATH_ATTR, CONFIG_ATTR) \
 | 
					
						
							|  |  |  |         if (config->CONFIG_ATTR) { \ | 
					
						
							| 
									
										
										
										
											2019-09-24 17:44:15 +02:00
										 |  |  |             PyMem_RawFree(pathconfig->PATH_ATTR); \ | 
					
						
							|  |  |  |             pathconfig->PATH_ATTR = NULL; \ | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |             if (copy_wstr(&pathconfig->PATH_ATTR, config->CONFIG_ATTR) < 0) { \ | 
					
						
							|  |  |  |                 goto no_memory; \ | 
					
						
							|  |  |  |             } \ | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     COPY_CONFIG(program_full_path, executable); | 
					
						
							|  |  |  |     COPY_CONFIG(prefix, prefix); | 
					
						
							|  |  |  |     COPY_CONFIG(exec_prefix, exec_prefix); | 
					
						
							|  |  |  |     COPY_CONFIG(program_name, program_name); | 
					
						
							|  |  |  |     COPY_CONFIG(home, home); | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     COPY_CONFIG(base_executable, base_executable); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef COPY_CONFIG
 | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |     goto done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | no_memory: | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-08 00:20:37 +02:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | _PyPathConfig_AsDict(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *dict = PyDict_New(); | 
					
						
							|  |  |  |     if (dict == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SET_ITEM(KEY, EXPR) \
 | 
					
						
							|  |  |  |         do { \ | 
					
						
							|  |  |  |             PyObject *obj = (EXPR); \ | 
					
						
							|  |  |  |             if (obj == NULL) { \ | 
					
						
							|  |  |  |                 goto fail; \ | 
					
						
							|  |  |  |             } \ | 
					
						
							|  |  |  |             int res = PyDict_SetItemString(dict, KEY, obj); \ | 
					
						
							|  |  |  |             Py_DECREF(obj); \ | 
					
						
							|  |  |  |             if (res < 0) { \ | 
					
						
							|  |  |  |                 goto fail; \ | 
					
						
							|  |  |  |             } \ | 
					
						
							|  |  |  |         } while (0) | 
					
						
							|  |  |  | #define SET_ITEM_STR(KEY) \
 | 
					
						
							|  |  |  |         SET_ITEM(#KEY, \ | 
					
						
							|  |  |  |             (_Py_path_config.KEY \ | 
					
						
							|  |  |  |              ? PyUnicode_FromWideChar(_Py_path_config.KEY, -1) \ | 
					
						
							|  |  |  |              : (Py_INCREF(Py_None), Py_None))) | 
					
						
							|  |  |  | #define SET_ITEM_INT(KEY) \
 | 
					
						
							|  |  |  |         SET_ITEM(#KEY, PyLong_FromLong(_Py_path_config.KEY)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SET_ITEM_STR(program_full_path); | 
					
						
							|  |  |  |     SET_ITEM_STR(prefix); | 
					
						
							|  |  |  |     SET_ITEM_STR(exec_prefix); | 
					
						
							|  |  |  |     SET_ITEM_STR(module_search_path); | 
					
						
							|  |  |  |     SET_ITEM_STR(program_name); | 
					
						
							|  |  |  |     SET_ITEM_STR(home); | 
					
						
							|  |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     SET_ITEM_INT(isolated); | 
					
						
							|  |  |  |     SET_ITEM_INT(site_import); | 
					
						
							|  |  |  |     SET_ITEM_STR(base_executable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         wchar_t py3path[MAX_PATH]; | 
					
						
							|  |  |  |         HMODULE hPython3 = GetModuleHandleW(PY3_DLLNAME); | 
					
						
							|  |  |  |         PyObject *obj; | 
					
						
							|  |  |  |         if (hPython3 | 
					
						
							|  |  |  |             && GetModuleFileNameW(hPython3, py3path, Py_ARRAY_LENGTH(py3path))) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             obj = PyUnicode_FromWideChar(py3path, -1); | 
					
						
							|  |  |  |             if (obj == NULL) { | 
					
						
							|  |  |  |                 goto fail; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             obj = Py_None; | 
					
						
							|  |  |  |             Py_INCREF(obj); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (PyDict_SetItemString(dict, "python3_dll", obj) < 0) { | 
					
						
							|  |  |  |             Py_DECREF(obj); | 
					
						
							|  |  |  |             goto fail; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Py_DECREF(obj); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef SET_ITEM
 | 
					
						
							|  |  |  | #undef SET_ITEM_STR
 | 
					
						
							|  |  |  | #undef SET_ITEM_INT
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return dict; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							|  |  |  |     Py_DECREF(dict); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-26 15:51:50 +02:00
										 |  |  | PyStatus | 
					
						
							|  |  |  | _PyConfig_WritePathConfig(const PyConfig *config) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return pathconfig_set_from_config(&_Py_path_config, config); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							|  |  |  | config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     assert(!config->module_search_paths_set); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     _PyWideStringList_Clear(&config->module_search_paths); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     const wchar_t *sys_path = pathconfig->module_search_path; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |     const wchar_t delim = DELIM; | 
					
						
							|  |  |  |     while (1) { | 
					
						
							| 
									
										
										
										
											2020-01-09 09:14:11 +00:00
										 |  |  |         const wchar_t *p = wcschr(sys_path, delim); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         if (p == NULL) { | 
					
						
							|  |  |  |             p = sys_path + wcslen(sys_path); /* End of string */ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         size_t path_len = (p - sys_path); | 
					
						
							|  |  |  |         wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); | 
					
						
							|  |  |  |         if (path == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         memcpy(path, sys_path, path_len * sizeof(wchar_t)); | 
					
						
							|  |  |  |         path[path_len] = L'\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         PyStatus status = PyWideStringList_Append(&config->module_search_paths, path); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         PyMem_RawFree(path); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             return status; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (*p == '\0') { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         sys_path = p + 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     config->module_search_paths_set = 1; | 
					
						
							|  |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | /* Calculate the path configuration:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    - exec_prefix | 
					
						
							|  |  |  |    - module_search_path | 
					
						
							|  |  |  |    - prefix | 
					
						
							|  |  |  |    - program_full_path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    On Windows, more fields are calculated: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    - base_executable | 
					
						
							|  |  |  |    - isolated | 
					
						
							|  |  |  |    - site_import | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    On other platforms, isolated and site_import are left unchanged, and | 
					
						
							|  |  |  |    _PyConfig_InitPathConfig() copies executable to base_executable (if it's not | 
					
						
							|  |  |  |    set). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Priority, highest to lowest: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    - PyConfig | 
					
						
							|  |  |  |    - _Py_path_config: set by Py_SetPath(), Py_SetPythonHome() | 
					
						
							|  |  |  |      and Py_SetProgramName() | 
					
						
							|  |  |  |    - _PyPathConfig_Calculate() | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  | pathconfig_init(_PyPathConfig *pathconfig, const PyConfig *config, | 
					
						
							|  |  |  |                 int compute_path_config) | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     PyStatus status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = pathconfig_copy(pathconfig, &_Py_path_config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status = pathconfig_set_from_config(pathconfig, config); | 
					
						
							|  |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |         goto done; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |     if (compute_path_config) { | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |         status = _PyPathConfig_Calculate(pathconfig, config); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  |     return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | static PyStatus | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  | config_init_pathconfig(PyConfig *config, int compute_path_config) | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     _PyPathConfig pathconfig = _PyPathConfig_INIT; | 
					
						
							|  |  |  |     PyStatus status; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |     status = pathconfig_init(&pathconfig, config, compute_path_config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |         goto done; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |     if (!config->module_search_paths_set | 
					
						
							|  |  |  |         && pathconfig.module_search_path != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         status = config_init_module_search_paths(config, &pathconfig); | 
					
						
							|  |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |             goto done; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | #define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |         if (config->CONFIG_ATTR == NULL && pathconfig.PATH_ATTR != NULL) { \ | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |             if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \ | 
					
						
							|  |  |  |                 goto no_memory; \ | 
					
						
							|  |  |  |             } \ | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     if (config->executable != NULL && config->base_executable == NULL) { | 
					
						
							|  |  |  |         /* If executable is set explicitly in the configuration,
 | 
					
						
							|  |  |  |            ignore calculated base_executable: _PyConfig_InitPathConfig() | 
					
						
							|  |  |  |            will copy executable to base_executable */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         COPY_ATTR(base_executable, base_executable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     COPY_ATTR(program_full_path, executable); | 
					
						
							|  |  |  |     COPY_ATTR(prefix, prefix); | 
					
						
							|  |  |  |     COPY_ATTR(exec_prefix, exec_prefix); | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | #undef COPY_ATTR
 | 
					
						
							| 
									
										
										
										
											2019-06-29 10:34:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  |     /* If a ._pth file is found: isolated and site_import are overriden */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (pathconfig.isolated != -1) { | 
					
						
							|  |  |  |         config->isolated = pathconfig.isolated; | 
					
						
							| 
									
										
										
										
											2018-07-21 03:54:20 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (pathconfig.site_import != -1) { | 
					
						
							|  |  |  |         config->site_import = pathconfig.site_import; | 
					
						
							| 
									
										
										
										
											2018-07-21 03:54:20 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-07-21 03:54:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     status = _PyStatus_OK(); | 
					
						
							|  |  |  |     goto done; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | no_memory: | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     status = _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  | done: | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     pathconfig_clear(&pathconfig); | 
					
						
							|  |  |  |     return status; | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | PyStatus | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  | _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     /* Do we need to calculate the path? */ | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     if (!config->module_search_paths_set | 
					
						
							| 
									
										
										
										
											2019-09-26 02:22:35 +02:00
										 |  |  |         || config->executable == NULL | 
					
						
							|  |  |  |         || config->prefix == NULL | 
					
						
							|  |  |  |         || config->exec_prefix == NULL) | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |         PyStatus status = config_init_pathconfig(config, compute_path_config); | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         if (_PyStatus_EXCEPTION(status)) { | 
					
						
							|  |  |  |             return status; | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |     if (config->base_prefix == NULL && config->prefix != NULL) { | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |         if (copy_wstr(&config->base_prefix, config->prefix) < 0) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |     if (config->base_exec_prefix == NULL && config->exec_prefix != NULL) { | 
					
						
							| 
									
										
										
										
											2018-11-17 20:41:48 -08:00
										 |  |  |         if (copy_wstr(&config->base_exec_prefix, | 
					
						
							|  |  |  |                       config->exec_prefix) < 0) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |             return _PyStatus_NO_MEMORY(); | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-29 10:34:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |     if (config->base_executable == NULL && config->executable != NULL) { | 
					
						
							| 
									
										
										
										
											2019-06-29 10:34:11 -07:00
										 |  |  |         if (copy_wstr(&config->base_executable, | 
					
						
							|  |  |  |                       config->executable) < 0) { | 
					
						
							|  |  |  |             return _PyStatus_NO_MEMORY(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2018-07-25 02:49:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | /* External interface */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  | static void _Py_NO_RETURN | 
					
						
							|  |  |  | path_out_of_memory(const char *func) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _Py_FatalErrorFunc(func, "out of memory"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | void | 
					
						
							|  |  |  | Py_SetPath(const wchar_t *path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (path == NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |         pathconfig_clear(&_Py_path_config); | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |     PyMem_RawFree(_Py_path_config.prefix); | 
					
						
							|  |  |  |     PyMem_RawFree(_Py_path_config.exec_prefix); | 
					
						
							|  |  |  |     PyMem_RawFree(_Py_path_config.module_search_path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _Py_path_config.prefix = _PyMem_RawWcsdup(L""); | 
					
						
							|  |  |  |     _Py_path_config.exec_prefix = _PyMem_RawWcsdup(L""); | 
					
						
							|  |  |  |     _Py_path_config.module_search_path = _PyMem_RawWcsdup(path); | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-10 21:10:22 +01:00
										 |  |  |     if (_Py_path_config.prefix == NULL | 
					
						
							| 
									
										
										
										
											2019-09-23 18:47:29 +02:00
										 |  |  |         || _Py_path_config.exec_prefix == NULL | 
					
						
							|  |  |  |         || _Py_path_config.module_search_path == NULL) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         path_out_of_memory(__func__); | 
					
						
							| 
									
										
										
										
											2018-07-21 02:06:16 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2017-12-12 13:55:04 +02:00
										 |  |  | Py_SetPythonHome(const wchar_t *home) | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (home == NULL) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_RawFree(_Py_path_config.home); | 
					
						
							|  |  |  |     _Py_path_config.home = _PyMem_RawWcsdup(home); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_Py_path_config.home == NULL) { | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         path_out_of_memory(__func__); | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2017-12-12 13:55:04 +02:00
										 |  |  | Py_SetProgramName(const wchar_t *program_name) | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (program_name == NULL || program_name[0] == L'\0') { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_RawFree(_Py_path_config.program_name); | 
					
						
							|  |  |  |     _Py_path_config.program_name = _PyMem_RawWcsdup(program_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_Py_path_config.program_name == NULL) { | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         path_out_of_memory(__func__); | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 20:41:48 -08:00
										 |  |  | void | 
					
						
							|  |  |  | _Py_SetProgramFullPath(const wchar_t *program_full_path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (program_full_path == NULL || program_full_path[0] == L'\0') { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMemAllocatorEx old_alloc; | 
					
						
							|  |  |  |     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_RawFree(_Py_path_config.program_full_path); | 
					
						
							|  |  |  |     _Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_Py_path_config.program_full_path == NULL) { | 
					
						
							| 
									
										
										
										
											2020-03-25 19:27:36 +01:00
										 |  |  |         path_out_of_memory(__func__); | 
					
						
							| 
									
										
										
										
											2018-11-17 20:41:48 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | wchar_t * | 
					
						
							|  |  |  | Py_GetPath(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _Py_path_config.module_search_path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | wchar_t * | 
					
						
							|  |  |  | Py_GetPrefix(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _Py_path_config.prefix; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | wchar_t * | 
					
						
							|  |  |  | Py_GetExecPrefix(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _Py_path_config.exec_prefix; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | wchar_t * | 
					
						
							|  |  |  | Py_GetProgramFullPath(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _Py_path_config.program_full_path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | wchar_t* | 
					
						
							|  |  |  | Py_GetPythonHome(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _Py_path_config.home; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | wchar_t * | 
					
						
							|  |  |  | Py_GetProgramName(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _Py_path_config.program_name; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 16:09:27 +01:00
										 |  |  | /* Compute module search path from argv[0] or the current working
 | 
					
						
							|  |  |  |    directory ("-m module" case) which will be prepended to sys.argv: | 
					
						
							|  |  |  |    sys.path[0]. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 16:39:26 +02:00
										 |  |  |    Return 1 if the path is correctly resolved and written into *path0_p. | 
					
						
							| 
									
										
										
										
											2019-03-19 16:09:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 16:39:26 +02:00
										 |  |  |    Return 0 if it fails to resolve the full path. For example, return 0 if the | 
					
						
							|  |  |  |    current working directory has been removed (bpo-36236) or if argv is empty. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Raise an exception and return -1 on error. | 
					
						
							| 
									
										
										
										
											2019-03-19 16:09:27 +01:00
										 |  |  |    */ | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  | _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-27 16:39:22 +02:00
										 |  |  |     assert(_PyWideStringList_CheckConsistency(argv)); | 
					
						
							| 
									
										
										
										
											2019-03-15 15:08:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |     if (argv->length == 0) { | 
					
						
							|  |  |  |         /* Leave sys.path unchanged if sys.argv is empty */ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     wchar_t *argv0 = argv->items[0]; | 
					
						
							|  |  |  |     int have_module_arg = (wcscmp(argv0, L"-m") == 0); | 
					
						
							|  |  |  |     int have_script_arg = (!have_module_arg && (wcscmp(argv0, L"-c") != 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     wchar_t *path0 = argv0; | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |     Py_ssize_t n = 0; | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_REALPATH
 | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |     wchar_t fullpath[MAXPATHLEN]; | 
					
						
							|  |  |  | #elif defined(MS_WINDOWS)
 | 
					
						
							|  |  |  |     wchar_t fullpath[MAX_PATH]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 23:03:10 +10:00
										 |  |  |     if (have_module_arg) { | 
					
						
							| 
									
										
										
										
											2019-03-19 16:09:27 +01:00
										 |  |  | #if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) { | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         path0 = fullpath; | 
					
						
							| 
									
										
										
										
											2019-03-19 16:09:27 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         path0 = L"."; | 
					
						
							| 
									
										
										
										
											2019-03-19 16:09:27 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         n = wcslen(path0); | 
					
						
							| 
									
										
										
										
											2018-03-25 23:03:10 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_READLINK
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |     wchar_t link[MAXPATHLEN + 1]; | 
					
						
							|  |  |  |     int nr = 0; | 
					
						
							| 
									
										
										
										
											2020-06-22 00:27:20 -07:00
										 |  |  |     wchar_t path0copy[2 * MAXPATHLEN + 1]; | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (have_script_arg) { | 
					
						
							|  |  |  |         nr = _Py_wreadlink(path0, link, Py_ARRAY_LENGTH(link)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |     if (nr > 0) { | 
					
						
							|  |  |  |         /* It's a symlink */ | 
					
						
							|  |  |  |         link[nr] = '\0'; | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         if (link[0] == SEP) { | 
					
						
							|  |  |  |             path0 = link; /* Link to absolute path */ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (wcschr(link, SEP) == NULL) { | 
					
						
							|  |  |  |             /* Link without path */ | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |         else { | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |             /* Must join(dirname(path0), link) */ | 
					
						
							|  |  |  |             wchar_t *q = wcsrchr(path0, SEP); | 
					
						
							|  |  |  |             if (q == NULL) { | 
					
						
							|  |  |  |                 /* path0 without path */ | 
					
						
							|  |  |  |                 path0 = link; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |             else { | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |                 /* Must make a copy, path0copy has room for 2 * MAXPATHLEN */ | 
					
						
							|  |  |  |                 wcsncpy(path0copy, path0, MAXPATHLEN); | 
					
						
							|  |  |  |                 q = wcsrchr(path0copy, SEP); | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |                 wcsncpy(q+1, link, MAXPATHLEN); | 
					
						
							|  |  |  |                 q[MAXPATHLEN + 1] = L'\0'; | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |                 path0 = path0copy; | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif /* HAVE_READLINK */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |     wchar_t *p = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  | #if SEP == '\\'
 | 
					
						
							|  |  |  |     /* Special case for Microsoft filename syntax */ | 
					
						
							| 
									
										
										
										
											2018-03-25 23:03:10 +10:00
										 |  |  |     if (have_script_arg) { | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |         wchar_t *q; | 
					
						
							|  |  |  | #if defined(MS_WINDOWS)
 | 
					
						
							|  |  |  |         /* Replace the first element in argv with the full path. */ | 
					
						
							|  |  |  |         wchar_t *ptemp; | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         if (GetFullPathNameW(path0, | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |                            Py_ARRAY_LENGTH(fullpath), | 
					
						
							|  |  |  |                            fullpath, | 
					
						
							|  |  |  |                            &ptemp)) { | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |             path0 = fullpath; | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         p = wcsrchr(path0, SEP); | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |         /* Test for alternate separator */ | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         q = wcsrchr(p ? p : path0, '/'); | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |         if (q != NULL) | 
					
						
							|  |  |  |             p = q; | 
					
						
							|  |  |  |         if (p != NULL) { | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |             n = p + 1 - path0; | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |             if (n > 1 && p[-1] != ':') | 
					
						
							|  |  |  |                 n--; /* Drop trailing separator */ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     /* All other filename syntaxes */ | 
					
						
							| 
									
										
										
										
											2018-03-25 23:03:10 +10:00
										 |  |  |     if (have_script_arg) { | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  | #if defined(HAVE_REALPATH)
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         if (_Py_wrealpath(path0, fullpath, Py_ARRAY_LENGTH(fullpath))) { | 
					
						
							|  |  |  |             path0 = fullpath; | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         p = wcsrchr(path0, SEP); | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (p != NULL) { | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         n = p + 1 - path0; | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  | #if SEP == '/' /* Special case for Unix filename syntax */
 | 
					
						
							| 
									
										
										
										
											2019-03-19 18:22:55 +01:00
										 |  |  |         if (n > 1) { | 
					
						
							|  |  |  |             /* Drop trailing separator */ | 
					
						
							|  |  |  |             n--; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  | #endif /* Unix */
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif /* All others */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 16:39:26 +02:00
										 |  |  |     PyObject *path0_obj = PyUnicode_FromWideChar(path0, n); | 
					
						
							|  |  |  |     if (path0_obj == NULL) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *path0_p = path0_obj; | 
					
						
							| 
									
										
										
										
											2019-03-19 16:09:27 +01:00
										 |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2017-12-13 21:05:57 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 20:26:55 -08:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | #define WCSTOK wcstok_s
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define WCSTOK wcstok
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  | /* Search for a prefix value in an environment file (pyvenv.cfg).
 | 
					
						
							| 
									
										
										
										
											2019-10-04 19:53:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |    - If found, copy it into *value_p: string which must be freed by | 
					
						
							|  |  |  |      PyMem_RawFree(). | 
					
						
							|  |  |  |    - If not found, *value_p is set to NULL. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | PyStatus | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  | _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key, | 
					
						
							| 
									
										
										
										
											2019-10-04 19:53:43 +02:00
										 |  |  |                        wchar_t **value_p) | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-04 19:53:43 +02:00
										 |  |  |     *value_p = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 02:58:14 +01:00
										 |  |  |     char buffer[MAXPATHLEN * 2 + 1];  /* allow extra for key, '=', etc. */ | 
					
						
							|  |  |  |     buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0'; | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     while (!feof(env_file)) { | 
					
						
							| 
									
										
										
										
											2019-03-19 02:58:14 +01:00
										 |  |  |         char * p = fgets(buffer, Py_ARRAY_LENGTH(buffer) - 1, env_file); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (p == NULL) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-18 11:15:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         size_t n = strlen(p); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  |         if (p[n - 1] != '\n') { | 
					
						
							|  |  |  |             /* line has overflowed - bail */ | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (p[0] == '#') { | 
					
						
							|  |  |  |             /* Comment - skip */ | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-18 11:15:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 01:46:25 +01:00
										 |  |  |         wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL); | 
					
						
							| 
									
										
										
										
											2018-01-15 10:45:49 +01:00
										 |  |  |         if (tmpbuffer) { | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  |             wchar_t * state; | 
					
						
							| 
									
										
										
										
											2019-02-02 20:26:55 -08:00
										 |  |  |             wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  |             if ((tok != NULL) && !wcscmp(tok, key)) { | 
					
						
							| 
									
										
										
										
											2019-02-02 20:26:55 -08:00
										 |  |  |                 tok = WCSTOK(NULL, L" \t", &state); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  |                 if ((tok != NULL) && !wcscmp(tok, L"=")) { | 
					
						
							| 
									
										
										
										
											2019-02-02 20:26:55 -08:00
										 |  |  |                     tok = WCSTOK(NULL, L"\r\n", &state); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  |                     if (tok != NULL) { | 
					
						
							| 
									
										
										
										
											2019-10-04 19:53:43 +02:00
										 |  |  |                         *value_p = _PyMem_RawWcsdup(tok); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  |                         PyMem_RawFree(tmpbuffer); | 
					
						
							| 
									
										
										
										
											2019-10-04 19:53:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         if (*value_p == NULL) { | 
					
						
							|  |  |  |                             return _PyStatus_NO_MEMORY(); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         /* found */ | 
					
						
							|  |  |  |                         return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             PyMem_RawFree(tmpbuffer); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-04 19:53:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* not found */ | 
					
						
							|  |  |  |     return _PyStatus_OK(); | 
					
						
							| 
									
										
										
										
											2017-12-21 16:49:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 13:39:15 +01:00
										 |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 |