summaryrefslogtreecommitdiffstats
path: root/PC/getpathp.c
diff options
context:
space:
mode:
Diffstat (limited to 'PC/getpathp.c')
-rw-r--r--PC/getpathp.c1201
1 files changed, 363 insertions, 838 deletions
diff --git a/PC/getpathp.c b/PC/getpathp.c
index 085caf1..461f9fc 100644
--- a/PC/getpathp.c
+++ b/PC/getpathp.c
@@ -1,14 +1,12 @@
/* Return the initial module search path. */
-/* Used by DOS, Windows 3.1, Windows 95/98, Windows NT. */
+/* Used by DOS, OS/2, Windows 3.1, Windows 95/98, Windows NT. */
/* ----------------------------------------------------------------
PATH RULES FOR WINDOWS:
This describes how sys.path is formed on Windows. It describes the
functionality, not the implementation (ie, the order in which these
- are actually fetched is different). The presence of a python._pth or
- pythonXY._pth file alongside the program overrides these rules - see
- below.
+ are actually fetched is different)
* Python always adds an empty entry at the start, which corresponds
to the current directory.
@@ -25,9 +23,9 @@
* We attempt to locate the "Python Home" - if the PYTHONHOME env var
is set, we believe it. Otherwise, we use the path of our host .EXE's
- to try and locate one of our "landmarks" and deduce our home.
+ to try and locate our "landmark" (lib\\os.py) and deduce our home.
- If we DO have a Python Home: The relevant sub-directories (Lib,
- DLLs, etc) are based on the Python Home
+ plat-win, lib-tk, etc) are based on the Python Home
- If we DO NOT have a Python Home, the core Python Path is
loaded from the registry. This is the main PythonPath key,
and both HKLM and HKCU are combined to form the path)
@@ -35,23 +33,7 @@
* Iff - we can not locate the Python Home, have not had a PYTHONPATH
specified, and can't locate any Registry entries (ie, we have _nothing_
we can assume is a good path), a default path with relative entries is
- used (eg. .\Lib;.\DLLs, etc)
-
-
- If a '._pth' file exists adjacent to the executable with the same base name
- (e.g. python._pth adjacent to python.exe) or adjacent to the shared library
- (e.g. python36._pth adjacent to python36.dll), it is used in preference to
- the above process. The shared library file takes precedence over the
- executable. The path file must contain a list of paths to add to sys.path,
- one per line. Each path is relative to the directory containing the file.
- Blank lines and comments beginning with '#' are permitted.
-
- In the presence of this ._pth file, no other paths are added to the search
- path, the registry finder is not enabled, site.py is not imported and
- isolated mode is enabled. The site package can be enabled by including a
- line reading "import site"; no other imports are recognized. Any invalid
- entry (other than directories that do not exist) will result in immediate
- termination of the program.
+ used (eg. .\Lib;.\plat-win, etc)
The end result of all this is:
@@ -69,29 +51,16 @@
exe, some very strange installation setup) you get a path with
some default, but relative, paths.
- * An embedding application can use Py_SetPath() to override all of
- these automatic path computations.
-
- * An install of Python can fully specify the contents of sys.path using
- either a 'EXENAME._pth' or 'DLLNAME._pth' file, optionally including
- "import site" to enable the site module.
-
---------------------------------------------------------------- */
#include "Python.h"
-#include "pycore_initconfig.h" /* PyStatus */
-#include "pycore_pathconfig.h" /* _PyPathConfig */
-#include "pycore_pystate.h"
#include "osdefs.h"
-#include <wchar.h>
-
-#ifndef MS_WINDOWS
-#error getpathp.c should only be built on Windows
-#endif
+#ifdef MS_WINDOWS
#include <windows.h>
-#include <shlwapi.h>
+#include <tchar.h>
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -110,36 +79,20 @@
* The approach is an adaptation for Windows of the strategy used in
* ../Modules/getpath.c; it uses the Windows Registry as one of its
* information sources.
- *
- * Py_SetPath() can be used to override this mechanism. Call Py_SetPath
- * with a semicolon separated path prior to calling Py_Initialize.
*/
#ifndef LANDMARK
-# define LANDMARK L"lib\\os.py"
+#define LANDMARK "lib\\os.py"
#endif
-#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow")
+static char prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char dllpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
-typedef struct {
- const wchar_t *path_env; /* PATH environment variable */
- const wchar_t *home; /* PYTHONHOME environment variable */
-
- /* Registry key "Software\Python\PythonCore\X.Y\PythonPath"
- where X.Y is the Python version (major.minor) */
- wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */
- wchar_t *user_path; /* from HKEY_CURRENT_USER */
-
- wchar_t *dll_path;
-
- const wchar_t *pythonpath_env;
-} PyCalculatePath;
-
-
-/* determine if "ch" is a separator character */
static int
-is_sep(wchar_t ch)
+is_sep(char ch) /* determine if "ch" is a separator character */
{
#ifdef ALTSEP
return ch == SEP || ch == ALTSEP;
@@ -148,17 +101,13 @@ is_sep(wchar_t ch)
#endif
}
-
/* assumes 'dir' null terminated in bounds. Never writes
- beyond existing terminator. */
+ beyond existing terminator.
+*/
static void
-reduce(wchar_t *dir)
+reduce(char *dir)
{
- size_t i = wcsnlen_s(dir, MAXPATHLEN+1);
- if (i >= MAXPATHLEN+1) {
- Py_FatalError("buffer overflow in getpathp.c's reduce()");
- }
-
+ size_t i = strlen(dir);
while (i > 0 && !is_sep(dir[i]))
--i;
dir[i] = '\0';
@@ -166,72 +115,30 @@ reduce(wchar_t *dir)
static int
-change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
-{
- size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
- size_t i = src_len;
- if (i >= MAXPATHLEN+1) {
- Py_FatalError("buffer overflow in getpathp.c's reduce()");
- }
-
- while (i > 0 && src[i] != '.' && !is_sep(src[i]))
- --i;
-
- if (i == 0) {
- dest[0] = '\0';
- return -1;
- }
-
- if (is_sep(src[i])) {
- i = src_len;
- }
-
- if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
- wcscat_s(dest, MAXPATHLEN+1, ext))
- {
- dest[0] = '\0';
- return -1;
- }
-
- return 0;
-}
-
-
-static int
-exists(const wchar_t *filename)
+exists(char *filename)
{
- return GetFileAttributesW(filename) != 0xFFFFFFFF;
+ struct stat buf;
+ return stat(filename, &buf) == 0;
}
-
-/* Is module -- check for .pyc too.
- Assumes 'filename' MAXPATHLEN+1 bytes long -
- may extend 'filename' by one character. */
+/* Assumes 'filename' MAXPATHLEN+1 bytes long -
+ may extend 'filename' by one character.
+*/
static int
-ismodule(wchar_t *filename, int update_filename)
+ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
{
- size_t n;
-
- if (exists(filename)) {
+ if (exists(filename))
return 1;
- }
/* Check for the compiled version of prefix. */
- n = wcsnlen_s(filename, MAXPATHLEN+1);
- if (n < MAXPATHLEN) {
- int exist = 0;
- filename[n] = L'c';
- filename[n + 1] = L'\0';
- exist = exists(filename);
- if (!update_filename) {
- filename[n] = L'\0';
- }
- return exist;
+ if (strlen(filename) < MAXPATHLEN) {
+ strcat(filename, Py_OptimizeFlag ? "o" : "c");
+ if (exists(filename))
+ return 1;
}
return 0;
}
-
/* Add a path component, by appending stuff to buffer.
buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
NUL-terminated string with no more than MAXPATHLEN characters (not counting
@@ -241,113 +148,65 @@ ismodule(wchar_t *filename, int update_filename)
than MAXPATHLEN characters at exit. If stuff is too long, only as much of
stuff as fits will be appended.
*/
-
-static int _PathCchCombineEx_Initialized = 0;
-typedef HRESULT(__stdcall *PPathCchCombineEx) (PWSTR pszPathOut, size_t cchPathOut,
- PCWSTR pszPathIn, PCWSTR pszMore,
- unsigned long dwFlags);
-static PPathCchCombineEx _PathCchCombineEx;
-
static void
-join(wchar_t *buffer, const wchar_t *stuff)
-{
- if (_PathCchCombineEx_Initialized == 0) {
- HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
- if (pathapi) {
- _PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
- }
- else {
- _PathCchCombineEx = NULL;
- }
- _PathCchCombineEx_Initialized = 1;
- }
-
- if (_PathCchCombineEx) {
- if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0))) {
- Py_FatalError("buffer overflow in getpathp.c's join()");
- }
- } else {
- if (!PathCombineW(buffer, buffer, stuff)) {
- Py_FatalError("buffer overflow in getpathp.c's join()");
- }
- }
-}
-
-static int _PathCchCanonicalizeEx_Initialized = 0;
-typedef HRESULT(__stdcall *PPathCchCanonicalizeEx) (PWSTR pszPathOut, size_t cchPathOut,
- PCWSTR pszPathIn, unsigned long dwFlags);
-static PPathCchCanonicalizeEx _PathCchCanonicalizeEx;
-
-/* Call PathCchCanonicalizeEx(path): remove navigation elements such as "."
- and ".." to produce a direct, well-formed path. */
-static PyStatus
-canonicalize(wchar_t *buffer, const wchar_t *path)
+join(char *buffer, char *stuff)
{
- if (buffer == NULL) {
- return _PyStatus_NO_MEMORY();
- }
-
- if (_PathCchCanonicalizeEx_Initialized == 0) {
- HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
- if (pathapi) {
- _PathCchCanonicalizeEx = (PPathCchCanonicalizeEx)GetProcAddress(pathapi, "PathCchCanonicalizeEx");
- }
- else {
- _PathCchCanonicalizeEx = NULL;
- }
- _PathCchCanonicalizeEx_Initialized = 1;
- }
-
- if (_PathCchCanonicalizeEx) {
- if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- }
+ size_t n, k;
+ if (is_sep(stuff[0]))
+ n = 0;
else {
- if (!PathCanonicalizeW(buffer, path)) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- }
- return _PyStatus_OK();
+ n = strlen(buffer);
+ if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
+ buffer[n++] = SEP;
+ }
+ if (n > MAXPATHLEN)
+ Py_FatalError("buffer overflow in getpathp.c's joinpath()");
+ k = strlen(stuff);
+ if (n + k > MAXPATHLEN)
+ k = MAXPATHLEN - n;
+ strncpy(buffer+n, stuff, k);
+ buffer[n+k] = '\0';
}
-
/* gotlandmark only called by search_for_prefix, which ensures
'prefix' is null terminated in bounds. join() ensures
- 'landmark' can not overflow prefix if too long. */
+ 'landmark' can not overflow prefix if too long.
+*/
static int
-gotlandmark(const wchar_t *prefix, const wchar_t *landmark)
+gotlandmark(char *landmark)
{
- wchar_t filename[MAXPATHLEN+1];
- memset(filename, 0, sizeof(filename));
- wcscpy_s(filename, Py_ARRAY_LENGTH(filename), prefix);
- join(filename, landmark);
- return ismodule(filename, FALSE);
+ int ok;
+ Py_ssize_t n;
+
+ n = strlen(prefix);
+ join(prefix, landmark);
+ ok = ismodule(prefix);
+ prefix[n] = '\0';
+ return ok;
}
-
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
assumption provided by only caller, calculate_path() */
static int
-search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *landmark)
+search_for_prefix(char *argv0_path, char *landmark)
{
/* Search from argv0_path, until landmark is found */
- wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path);
+ strcpy(prefix, argv0_path);
do {
- if (gotlandmark(prefix, landmark)) {
+ if (gotlandmark(landmark))
return 1;
- }
reduce(prefix);
} while (prefix[0]);
return 0;
}
-
+#ifdef MS_WINDOWS
#ifdef Py_ENABLE_SHARED
/* a string loaded from the DLL at startup.*/
extern const char *PyWin_DLLVersionString;
+
/* Load a PYTHONPATH value from the registry.
Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
@@ -360,92 +219,78 @@ extern const char *PyWin_DLLVersionString;
work on Win16, where the buffer sizes werent available
in advance. It could be simplied now Win16/Win32s is dead!
*/
-static wchar_t *
+
+static char *
getpythonregpath(HKEY keyBase, int skipcore)
{
HKEY newKey = 0;
DWORD dataSize = 0;
DWORD numKeys = 0;
LONG rc;
- wchar_t *retval = NULL;
- WCHAR *dataBuf = NULL;
- static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\";
- static const WCHAR keySuffix[] = L"\\PythonPath";
- size_t versionLen, keyBufLen;
+ char *retval = NULL;
+ TCHAR *dataBuf = NULL;
+ static const TCHAR keyPrefix[] = _T("Software\\Python\\PythonCore\\");
+ static const TCHAR keySuffix[] = _T("\\PythonPath");
+ size_t versionLen;
DWORD index;
- WCHAR *keyBuf = NULL;
- WCHAR *keyBufPtr;
- WCHAR **ppPaths = NULL;
+ TCHAR *keyBuf = NULL;
+ TCHAR *keyBufPtr;
+ TCHAR **ppPaths = NULL;
/* Tried to use sysget("winver") but here is too early :-( */
- versionLen = strlen(PyWin_DLLVersionString);
+ versionLen = _tcslen(PyWin_DLLVersionString);
/* Space for all the chars, plus one \0 */
- keyBufLen = sizeof(keyPrefix) +
- sizeof(WCHAR)*(versionLen-1) +
- sizeof(keySuffix);
- keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen);
- if (keyBuf==NULL) {
- goto done;
- }
-
- memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR));
- keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1;
- mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen);
+ keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +
+ sizeof(TCHAR)*(versionLen-1) +
+ sizeof(keySuffix));
+ if (keyBuf==NULL) goto done;
+
+ memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(TCHAR));
+ keyBufPtr += sizeof(keyPrefix)/sizeof(TCHAR) - 1;
+ memcpy(keyBufPtr, PyWin_DLLVersionString, versionLen * sizeof(TCHAR));
keyBufPtr += versionLen;
/* NULL comes with this one! */
memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
/* Open the root Python key */
- rc=RegOpenKeyExW(keyBase,
+ rc=RegOpenKeyEx(keyBase,
keyBuf, /* subkey */
0, /* reserved */
KEY_READ,
&newKey);
- if (rc!=ERROR_SUCCESS) {
- goto done;
- }
+ if (rc!=ERROR_SUCCESS) goto done;
/* Find out how big our core buffer is, and how many subkeys we have */
rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,
NULL, NULL, &dataSize, NULL, NULL);
- if (rc!=ERROR_SUCCESS) {
- goto done;
- }
- if (skipcore) {
- dataSize = 0; /* Only count core ones if we want them! */
- }
+ if (rc!=ERROR_SUCCESS) goto done;
+ if (skipcore) dataSize = 0; /* Only count core ones if we want them! */
/* Allocate a temp array of char buffers, so we only need to loop
reading the registry once
*/
- ppPaths = PyMem_RawMalloc( sizeof(WCHAR *) * numKeys );
- if (ppPaths==NULL) {
- goto done;
- }
- memset(ppPaths, 0, sizeof(WCHAR *) * numKeys);
+ ppPaths = malloc( sizeof(TCHAR *) * numKeys );
+ if (ppPaths==NULL) goto done;
+ memset(ppPaths, 0, sizeof(TCHAR *) * numKeys);
/* Loop over all subkeys, allocating a temp sub-buffer. */
for(index=0;index<numKeys;index++) {
- WCHAR keyBuf[MAX_PATH+1];
+ TCHAR keyBuf[MAX_PATH+1];
HKEY subKey = 0;
DWORD reqdSize = MAX_PATH+1;
/* Get the sub-key name */
- DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize,
- NULL, NULL, NULL, NULL );
- if (rc!=ERROR_SUCCESS) {
- goto done;
- }
+ DWORD rc = RegEnumKeyEx(newKey, index, keyBuf, &reqdSize,
+ NULL, NULL, NULL, NULL );
+ if (rc!=ERROR_SUCCESS) goto done;
/* Open the sub-key */
- rc=RegOpenKeyExW(newKey,
+ rc=RegOpenKeyEx(newKey,
keyBuf, /* subkey */
0, /* reserved */
KEY_READ,
&subKey);
- if (rc!=ERROR_SUCCESS) {
- goto done;
- }
+ if (rc!=ERROR_SUCCESS) goto done;
/* Find the value of the buffer size, malloc, then read it */
- RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize);
+ RegQueryValueEx(subKey, NULL, 0, NULL, NULL, &reqdSize);
if (reqdSize) {
- ppPaths[index] = PyMem_RawMalloc(reqdSize);
+ ppPaths[index] = malloc(reqdSize);
if (ppPaths[index]) {
- RegQueryValueExW(subKey, NULL, 0, NULL,
+ RegQueryValueEx(subKey, NULL, 0, NULL,
(LPBYTE)ppPaths[index],
&reqdSize);
dataSize += reqdSize + 1; /* 1 for the ";" */
@@ -455,396 +300,233 @@ getpythonregpath(HKEY keyBase, int skipcore)
}
/* return null if no path to return */
- if (dataSize == 0) {
- goto done;
- }
+ if (dataSize == 0) goto done;
/* original datasize from RegQueryInfo doesn't include the \0 */
- dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR));
+ dataBuf = malloc((dataSize+1) * sizeof(TCHAR));
if (dataBuf) {
- WCHAR *szCur = dataBuf;
+ TCHAR *szCur = dataBuf;
+ DWORD reqdSize = dataSize;
/* Copy our collected strings */
for (index=0;index<numKeys;index++) {
if (index > 0) {
- *(szCur++) = L';';
+ *(szCur++) = _T(';');
dataSize--;
}
if (ppPaths[index]) {
- Py_ssize_t len = wcslen(ppPaths[index]);
- wcsncpy(szCur, ppPaths[index], len);
+ Py_ssize_t len = _tcslen(ppPaths[index]);
+ _tcsncpy(szCur, ppPaths[index], len);
szCur += len;
assert(dataSize > (DWORD)len);
dataSize -= (DWORD)len;
}
}
- if (skipcore) {
+ if (skipcore)
*szCur = '\0';
- }
else {
- /* If we have no values, we don't need a ';' */
+ /* If we have no values, we dont need a ';' */
if (numKeys) {
- *(szCur++) = L';';
+ *(szCur++) = _T(';');
dataSize--;
}
/* Now append the core path entries -
this will include the NULL
*/
- rc = RegQueryValueExW(newKey, NULL, 0, NULL,
- (LPBYTE)szCur, &dataSize);
- if (rc != ERROR_SUCCESS) {
- PyMem_RawFree(dataBuf);
- goto done;
- }
- }
- /* And set the result - caller must free */
+ rc = RegQueryValueEx(newKey, NULL, 0, NULL,
+ (LPBYTE)szCur, &dataSize);
+ }
+ /* And set the result - caller must free
+ If MBCS, it is fine as is. If Unicode, allocate new
+ buffer and convert.
+ */
+#ifdef UNICODE
+ retval = (char *)malloc(reqdSize+1);
+ if (retval)
+ WideCharToMultiByte(CP_ACP, 0,
+ dataBuf, -1, /* source */
+ retval, reqdSize+1, /* dest */
+ NULL, NULL);
+ free(dataBuf);
+#else
retval = dataBuf;
+#endif
}
done:
/* Loop freeing my temp buffers */
if (ppPaths) {
- for(index=0; index<numKeys; index++)
- PyMem_RawFree(ppPaths[index]);
- PyMem_RawFree(ppPaths);
+ for(index=0;index<numKeys;index++)
+ if (ppPaths[index]) free(ppPaths[index]);
+ free(ppPaths);
}
- if (newKey) {
+ if (newKey)
RegCloseKey(newKey);
- }
- PyMem_RawFree(keyBuf);
+ if (keyBuf)
+ free(keyBuf);
return retval;
}
#endif /* Py_ENABLE_SHARED */
+#endif /* MS_WINDOWS */
-
-wchar_t*
-_Py_GetDLLPath(void)
+static void
+get_progpath(void)
{
- wchar_t dll_path[MAXPATHLEN+1];
- memset(dll_path, 0, sizeof(dll_path));
+ extern char *Py_GetProgramName(void);
+ char *path = getenv("PATH");
+ char *prog = Py_GetProgramName();
-#ifdef Py_ENABLE_SHARED
+#ifdef MS_WINDOWS
extern HANDLE PyWin_DLLhModule;
- if (PyWin_DLLhModule) {
- if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
- dll_path[0] = 0;
- }
+#ifdef UNICODE
+ WCHAR wprogpath[MAXPATHLEN+1];
+ /* Windows documents that GetModuleFileName() will "truncate",
+ but makes no mention of the null terminator. Play it safe.
+ PLUS Windows itself defines MAX_PATH as the same, but anyway...
+ */
+#ifdef Py_ENABLE_SHARED
+ wprogpath[MAXPATHLEN]=_T('\0');
+ if (PyWin_DLLhModule &&
+ GetModuleFileName(PyWin_DLLhModule, wprogpath, MAXPATHLEN)) {
+ WideCharToMultiByte(CP_ACP, 0,
+ wprogpath, -1,
+ dllpath, MAXPATHLEN+1,
+ NULL, NULL);
}
#else
- dll_path[0] = 0;
+ dllpath[0] = 0;
#endif
-
- return _PyMem_RawWcsdup(dll_path);
-}
-
-
-static PyStatus
-get_program_full_path(_PyPathConfig *pathconfig)
-{
- PyStatus status;
- const wchar_t *pyvenv_launcher;
- wchar_t program_full_path[MAXPATHLEN+1];
- memset(program_full_path, 0, sizeof(program_full_path));
-
- if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) {
- /* GetModuleFileName should never fail when passed NULL */
- return _PyStatus_ERR("Cannot determine program path");
+ wprogpath[MAXPATHLEN]=_T('\0');
+ if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
+ WideCharToMultiByte(CP_ACP, 0,
+ wprogpath, -1,
+ progpath, MAXPATHLEN+1,
+ NULL, NULL);
+ return;
}
-
- /* The launcher may need to force the executable path to a
- * different environment, so override it here. */
- pyvenv_launcher = _wgetenv(L"__PYVENV_LAUNCHER__");
- if (pyvenv_launcher && pyvenv_launcher[0]) {
- /* If overridden, preserve the original full path */
- if (pathconfig->base_executable == NULL) {
- pathconfig->base_executable = PyMem_RawMalloc(
- sizeof(wchar_t) * (MAXPATHLEN + 1));
- if (pathconfig->base_executable == NULL) {
- return _PyStatus_NO_MEMORY();
- }
-
- status = canonicalize(pathconfig->base_executable,
- program_full_path);
- if (_PyStatus_EXCEPTION(status)) {
- return status;
+#else
+ /* static init of progpath ensures final char remains \0 */
+#ifdef Py_ENABLE_SHARED
+ if (PyWin_DLLhModule)
+ if (!GetModuleFileName(PyWin_DLLhModule, dllpath, MAXPATHLEN))
+ dllpath[0] = 0;
+#else
+ dllpath[0] = 0;
+#endif
+ if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
+ return;
+#endif
+#endif
+ if (prog == NULL || *prog == '\0')
+ prog = "python";
+
+ /* If there is no slash in the argv0 path, then we have to
+ * assume python is on the user's $PATH, since there's no
+ * other way to find a directory to start the search from. If
+ * $PATH isn't exported, you lose.
+ */
+#ifdef ALTSEP
+ if (strchr(prog, SEP) || strchr(prog, ALTSEP))
+#else
+ if (strchr(prog, SEP))
+#endif
+ strncpy(progpath, prog, MAXPATHLEN);
+ else if (path) {
+ while (1) {
+ char *delim = strchr(path, DELIM);
+
+ if (delim) {
+ size_t len = delim - path;
+ /* ensure we can't overwrite buffer */
+ len = min(MAXPATHLEN,len);
+ strncpy(progpath, path, len);
+ *(progpath + len) = '\0';
}
- }
-
- wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher);
- /* bpo-35873: Clear the environment variable to avoid it being
- * inherited by child processes. */
- _wputenv_s(L"__PYVENV_LAUNCHER__", L"");
- }
+ else
+ strncpy(progpath, path, MAXPATHLEN);
- if (pathconfig->program_full_path == NULL) {
- pathconfig->program_full_path = PyMem_RawMalloc(
- sizeof(wchar_t) * (MAXPATHLEN + 1));
- if (pathconfig->program_full_path == NULL) {
- return _PyStatus_NO_MEMORY();
- }
-
- status = canonicalize(pathconfig->program_full_path,
- program_full_path);
- if (_PyStatus_EXCEPTION(status)) {
- return status;
- }
- }
- return _PyStatus_OK();
-}
-
-
-static PyStatus
-read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path,
- int *found)
-{
- PyStatus status;
- wchar_t *buf = NULL;
- wchar_t *wline = NULL;
- FILE *sp_file;
-
- sp_file = _Py_wfopen(path, L"r");
- if (sp_file == NULL) {
- return _PyStatus_OK();
- }
-
- wcscpy_s(prefix, MAXPATHLEN+1, path);
- reduce(prefix);
- pathconfig->isolated = 1;
- pathconfig->site_import = 0;
-
- size_t bufsiz = MAXPATHLEN;
- size_t prefixlen = wcslen(prefix);
-
- buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
- if (buf == NULL) {
- status = _PyStatus_NO_MEMORY();
- goto done;
- }
- buf[0] = '\0';
-
- while (!feof(sp_file)) {
- char line[MAXPATHLEN + 1];
- char *p = fgets(line, Py_ARRAY_LENGTH(line), sp_file);
- if (!p) {
- break;
- }
- if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#') {
- continue;
- }
- while (*++p) {
- if (*p == '\r' || *p == '\n') {
- *p = '\0';
+ /* join() is safe for MAXPATHLEN+1 size buffer */
+ join(progpath, prog);
+ if (exists(progpath))
break;
- }
- }
- if (strcmp(line, "import site") == 0) {
- pathconfig->site_import = 1;
- continue;
- }
- else if (strncmp(line, "import ", 7) == 0) {
- status = _PyStatus_ERR("only 'import site' is supported "
- "in ._pth file");
- goto done;
- }
-
- DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0);
- wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
- if (wline == NULL) {
- status = _PyStatus_NO_MEMORY();
- goto done;
- }
- wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1);
- wline[wn] = '\0';
-
- size_t usedsiz = wcslen(buf);
- while (usedsiz + wn + prefixlen + 4 > bufsiz) {
- bufsiz += MAXPATHLEN;
- wchar_t *tmp = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) *
- sizeof(wchar_t));
- if (tmp == NULL) {
- status = _PyStatus_NO_MEMORY();
- goto done;
+ if (!delim) {
+ progpath[0] = '\0';
+ break;
}
- buf = tmp;
- }
-
- if (usedsiz) {
- wcscat_s(buf, bufsiz, L";");
- usedsiz += 1;
- }
-
- errno_t result;
- _Py_BEGIN_SUPPRESS_IPH
- result = wcscat_s(buf, bufsiz, prefix);
- _Py_END_SUPPRESS_IPH
-
- if (result == EINVAL) {
- status = _PyStatus_ERR("invalid argument during ._pth processing");
- goto done;
- } else if (result == ERANGE) {
- status = _PyStatus_ERR("buffer overflow during ._pth processing");
- goto done;
- }
-
- wchar_t *b = &buf[usedsiz];
- join(b, wline);
-
- PyMem_RawFree(wline);
- wline = NULL;
- }
-
- if (pathconfig->module_search_path == NULL) {
- pathconfig->module_search_path = _PyMem_RawWcsdup(buf);
- if (pathconfig->module_search_path == NULL) {
- status = _PyStatus_NO_MEMORY();
- goto done;
- }
- }
-
- *found = 1;
- status = _PyStatus_OK();
- goto done;
-
-done:
- PyMem_RawFree(buf);
- PyMem_RawFree(wline);
- fclose(sp_file);
- return status;
-}
-
-
-static int
-get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
- const _PyPathConfig *pathconfig)
-{
- if (calculate->dll_path[0]) {
- if (!change_ext(filename, calculate->dll_path, L"._pth") &&
- exists(filename))
- {
- return 1;
+ path = delim + 1;
}
}
- if (pathconfig->program_full_path[0]) {
- if (!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
- exists(filename))
- {
- return 1;
- }
- }
- return 0;
+ else
+ progpath[0] = '\0';
}
-
-static PyStatus
-calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
- wchar_t *prefix, int *found)
-{
- wchar_t filename[MAXPATHLEN+1];
-
- if (!get_pth_filename(calculate, filename, pathconfig)) {
- return _PyStatus_OK();
- }
-
- return read_pth_file(pathconfig, prefix, filename, found);
-}
-
-
-/* Search for an environment configuration file, first in the
- executable's directory and then in the parent directory.
- If found, open it for use when searching for prefixes.
-*/
-static PyStatus
-calculate_pyvenv_file(PyCalculatePath *calculate,
- wchar_t *argv0_path, size_t argv0_path_len)
-{
- wchar_t filename[MAXPATHLEN+1];
- const wchar_t *env_cfg = L"pyvenv.cfg";
-
- /* Filename: <argv0_path_len> / "pyvenv.cfg" */
- wcscpy_s(filename, MAXPATHLEN+1, argv0_path);
- join(filename, env_cfg);
-
- FILE *env_file = _Py_wfopen(filename, L"r");
- if (env_file == NULL) {
- errno = 0;
-
- /* Filename: <basename(basename(argv0_path_len))> / "pyvenv.cfg" */
- reduce(filename);
- reduce(filename);
- join(filename, env_cfg);
-
- env_file = _Py_wfopen(filename, L"r");
- if (env_file == NULL) {
- errno = 0;
- return _PyStatus_OK();
- }
- }
-
- /* Look for a 'home' variable and set argv0_path to it, if found */
- wchar_t *home = NULL;
- PyStatus status = _Py_FindEnvConfigValue(env_file, L"home", &home);
- if (_PyStatus_EXCEPTION(status)) {
- fclose(env_file);
- return status;
- }
- if (home) {
- wcscpy_s(argv0_path, argv0_path_len, home);
- PyMem_RawFree(home);
- }
- fclose(env_file);
- return _PyStatus_OK();
-}
-
-
static void
-calculate_home_prefix(PyCalculatePath *calculate,
- const wchar_t *argv0_path,
- const wchar_t *zip_path,
- wchar_t *prefix)
+calculate_path(void)
{
- if (calculate->home == NULL || *calculate->home == '\0') {
- if (zip_path[0] && exists(zip_path)) {
- wcscpy_s(prefix, MAXPATHLEN+1, zip_path);
- reduce(prefix);
- calculate->home = prefix;
- }
- else if (search_for_prefix(prefix, argv0_path, LANDMARK)) {
- calculate->home = prefix;
- }
- else {
- calculate->home = NULL;
- }
+ char argv0_path[MAXPATHLEN+1];
+ char *buf;
+ size_t bufsz;
+ char *pythonhome = Py_GetPythonHome();
+ char *envpath = Py_GETENV("PYTHONPATH");
+
+#ifdef MS_WINDOWS
+ int skiphome, skipdefault;
+ char *machinepath = NULL;
+ char *userpath = NULL;
+ char zip_path[MAXPATHLEN+1];
+ size_t len;
+#endif
+
+ get_progpath();
+ /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
+ strcpy(argv0_path, progpath);
+ reduce(argv0_path);
+ if (pythonhome == NULL || *pythonhome == '\0') {
+ if (search_for_prefix(argv0_path, LANDMARK))
+ pythonhome = prefix;
+ else
+ pythonhome = NULL;
+ }
+ else
+ strncpy(prefix, pythonhome, MAXPATHLEN);
+
+ if (envpath && *envpath == '\0')
+ envpath = NULL;
+
+
+#ifdef MS_WINDOWS
+ /* Calculate zip archive path */
+ if (dllpath[0]) /* use name of python DLL */
+ strncpy(zip_path, dllpath, MAXPATHLEN);
+ else /* use name of executable program */
+ strncpy(zip_path, progpath, MAXPATHLEN);
+ zip_path[MAXPATHLEN] = '\0';
+ len = strlen(zip_path);
+ if (len > 4) {
+ zip_path[len-3] = 'z'; /* change ending to "zip" */
+ zip_path[len-2] = 'i';
+ zip_path[len-1] = 'p';
}
else {
- wcscpy_s(prefix, MAXPATHLEN+1, calculate->home);
+ zip_path[0] = 0;
}
-}
-
-static PyStatus
-calculate_module_search_path(PyCalculatePath *calculate,
- _PyPathConfig *pathconfig,
- const wchar_t *argv0_path,
- wchar_t *prefix,
- const wchar_t *zip_path)
-{
- int skiphome = calculate->home==NULL ? 0 : 1;
+ skiphome = pythonhome==NULL ? 0 : 1;
#ifdef Py_ENABLE_SHARED
- calculate->machine_path = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
- calculate->user_path = getpythonregpath(HKEY_CURRENT_USER, skiphome);
+ machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
+ userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
#endif
- /* We only use the default relative PYTHONPATH if we haven't
+ /* We only use the default relative PYTHONPATH if we havent
anything better to use! */
- int skipdefault = (calculate->pythonpath_env != NULL ||
- calculate->home != NULL ||
- calculate->machine_path != NULL ||
- calculate->user_path != NULL);
+ skipdefault = envpath!=NULL || pythonhome!=NULL || \
+ machinepath!=NULL || userpath!=NULL;
+#endif
/* We need to construct a path from the following parts.
(1) the PYTHONPATH environment variable, if set;
(2) for Win32, the zip archive file path;
- (3) for Win32, the machine_path and user_path, if set;
+ (3) for Win32, the machinepath and userpath, if set;
(4) the PYTHONPATH config macro, with the leading "."
- of each component replaced with home, if set;
+ of each component replaced with pythonhome, if set;
(5) the directory containing the executable (argv0_path).
The length calculation calculates #4 first.
Extra rules:
@@ -853,110 +535,115 @@ calculate_module_search_path(PyCalculatePath *calculate,
*/
/* Calculate size of return buffer */
- size_t bufsz = 0;
- if (calculate->home != NULL) {
- const wchar_t *p;
+ if (pythonhome != NULL) {
+ char *p;
bufsz = 1;
for (p = PYTHONPATH; *p; p++) {
- if (*p == DELIM) {
+ if (*p == DELIM)
bufsz++; /* number of DELIM plus one */
- }
}
- bufsz *= wcslen(calculate->home);
- }
- bufsz += wcslen(PYTHONPATH) + 1;
- bufsz += wcslen(argv0_path) + 1;
- if (calculate->user_path) {
- bufsz += wcslen(calculate->user_path) + 1;
- }
- if (calculate->machine_path) {
- bufsz += wcslen(calculate->machine_path) + 1;
- }
- bufsz += wcslen(zip_path) + 1;
- if (calculate->pythonpath_env != NULL) {
- bufsz += wcslen(calculate->pythonpath_env) + 1;
- }
+ bufsz *= strlen(pythonhome);
+ }
+ else
+ bufsz = 0;
+ bufsz += strlen(PYTHONPATH) + 1;
+ bufsz += strlen(argv0_path) + 1;
+#ifdef MS_WINDOWS
+ if (userpath)
+ bufsz += strlen(userpath) + 1;
+ if (machinepath)
+ bufsz += strlen(machinepath) + 1;
+ bufsz += strlen(zip_path) + 1;
+#endif
+ if (envpath != NULL)
+ bufsz += strlen(envpath) + 1;
- wchar_t *buf, *start_buf;
- buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
+ module_search_path = buf = malloc(bufsz);
if (buf == NULL) {
- return _PyStatus_NO_MEMORY();
+ /* We can't exit, so print a warning and limp along */
+ fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
+ if (envpath) {
+ fprintf(stderr, "Using environment $PYTHONPATH.\n");
+ module_search_path = envpath;
+ }
+ else {
+ fprintf(stderr, "Using default static path.\n");
+ module_search_path = PYTHONPATH;
+ }
+#ifdef MS_WINDOWS
+ if (machinepath)
+ free(machinepath);
+ if (userpath)
+ free(userpath);
+#endif /* MS_WINDOWS */
+ return;
}
- start_buf = buf;
- if (calculate->pythonpath_env) {
- if (wcscpy_s(buf, bufsz - (buf - start_buf),
- calculate->pythonpath_env)) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- buf = wcschr(buf, L'\0');
+ if (envpath) {
+ strcpy(buf, envpath);
+ buf = strchr(buf, '\0');
*buf++ = DELIM;
}
+#ifdef MS_WINDOWS
if (zip_path[0]) {
- if (wcscpy_s(buf, bufsz - (buf - start_buf), zip_path)) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- buf = wcschr(buf, L'\0');
+ strcpy(buf, zip_path);
+ buf = strchr(buf, '\0');
*buf++ = DELIM;
}
- if (calculate->user_path) {
- if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->user_path)) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- buf = wcschr(buf, L'\0');
+ if (userpath) {
+ strcpy(buf, userpath);
+ buf = strchr(buf, '\0');
*buf++ = DELIM;
+ free(userpath);
}
- if (calculate->machine_path) {
- if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->machine_path)) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- buf = wcschr(buf, L'\0');
+ if (machinepath) {
+ strcpy(buf, machinepath);
+ buf = strchr(buf, '\0');
*buf++ = DELIM;
+ free(machinepath);
}
- if (calculate->home == NULL) {
+ if (pythonhome == NULL) {
if (!skipdefault) {
- if (wcscpy_s(buf, bufsz - (buf - start_buf), PYTHONPATH)) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- buf = wcschr(buf, L'\0');
- *buf++ = DELIM;
+ strcpy(buf, PYTHONPATH);
+ buf = strchr(buf, '\0');
}
- } else {
- const wchar_t *p = PYTHONPATH;
- const wchar_t *q;
+ }
+#else
+ if (pythonhome == NULL) {
+ strcpy(buf, PYTHONPATH);
+ buf = strchr(buf, '\0');
+ }
+#endif /* MS_WINDOWS */
+ else {
+ char *p = PYTHONPATH;
+ char *q;
size_t n;
for (;;) {
- q = wcschr(p, DELIM);
- if (q == NULL) {
- n = wcslen(p);
- }
- else {
+ q = strchr(p, DELIM);
+ if (q == NULL)
+ n = strlen(p);
+ else
n = q-p;
- }
if (p[0] == '.' && is_sep(p[1])) {
- if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->home)) {
- return INIT_ERR_BUFFER_OVERFLOW();
- }
- buf = wcschr(buf, L'\0');
+ strcpy(buf, pythonhome);
+ buf = strchr(buf, '\0');
p++;
n--;
}
- wcsncpy(buf, p, n);
+ strncpy(buf, p, n);
buf += n;
- *buf++ = DELIM;
- if (q == NULL) {
+ if (q == NULL)
break;
- }
+ *buf++ = DELIM;
p = q+1;
}
}
if (argv0_path) {
- wcscpy(buf, argv0_path);
- buf = wcschr(buf, L'\0');
*buf++ = DELIM;
+ strcpy(buf, argv0_path);
+ buf = strchr(buf, '\0');
}
- *(buf - 1) = L'\0';
-
+ *buf = '\0';
/* Now to pull one last hack/trick. If sys.prefix is
empty, then try and find it somewhere on the paths
we calculated. We scan backwards, as our general policy
@@ -965,225 +652,63 @@ calculate_module_search_path(PyCalculatePath *calculate,
on the path, and that our 'prefix' directory is
the parent of that.
*/
- if (prefix[0] == L'\0') {
- wchar_t lookBuf[MAXPATHLEN+1];
- const wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
+ if (*prefix=='\0') {
+ char lookBuf[MAXPATHLEN+1];
+ char *look = buf - 1; /* 'buf' is at the end of the buffer */
while (1) {
Py_ssize_t nchars;
- const wchar_t *lookEnd = look;
+ char *lookEnd = look;
/* 'look' will end up one character before the
start of the path in question - even if this
is one character before the start of the buffer
*/
- while (look >= start_buf && *look != DELIM)
+ while (look >= module_search_path && *look != DELIM)
look--;
nchars = lookEnd-look;
- wcsncpy(lookBuf, look+1, nchars);
- lookBuf[nchars] = L'\0';
+ strncpy(lookBuf, look+1, nchars);
+ lookBuf[nchars] = '\0';
/* Up one level to the parent */
reduce(lookBuf);
- if (search_for_prefix(prefix, lookBuf, LANDMARK)) {
+ if (search_for_prefix(lookBuf, LANDMARK)) {
break;
}
/* If we are out of paths to search - give up */
- if (look < start_buf) {
+ if (look < module_search_path)
break;
- }
look--;
}
}
-
- pathconfig->module_search_path = start_buf;
- return _PyStatus_OK();
}
-static PyStatus
-calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
-{
- PyStatus status;
-
- status = get_program_full_path(pathconfig);
- if (_PyStatus_EXCEPTION(status)) {
- return status;
- }
+/* External interface */
- /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */
- wchar_t argv0_path[MAXPATHLEN+1];
- memset(argv0_path, 0, sizeof(argv0_path));
-
- wcscpy_s(argv0_path, MAXPATHLEN+1, pathconfig->program_full_path);
- reduce(argv0_path);
-
- wchar_t prefix[MAXPATHLEN+1];
- memset(prefix, 0, sizeof(prefix));
-
- /* Search for a sys.path file */
- int pth_found = 0;
- status = calculate_pth_file(calculate, pathconfig, prefix, &pth_found);
- if (_PyStatus_EXCEPTION(status)) {
- return status;
- }
- if (pth_found) {
- goto done;
- }
-
- status = calculate_pyvenv_file(calculate,
- argv0_path, Py_ARRAY_LENGTH(argv0_path));
- if (_PyStatus_EXCEPTION(status)) {
- return status;
- }
-
- /* Calculate zip archive path from DLL or exe path */
- wchar_t zip_path[MAXPATHLEN+1];
- memset(zip_path, 0, sizeof(zip_path));
-
- change_ext(zip_path,
- calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path,
- L".zip");
-
- calculate_home_prefix(calculate, argv0_path, zip_path, prefix);
-
- if (pathconfig->module_search_path == NULL) {
- status = calculate_module_search_path(calculate, pathconfig,
- argv0_path, prefix, zip_path);
- if (_PyStatus_EXCEPTION(status)) {
- return status;
- }
- }
-
-done:
- if (pathconfig->prefix == NULL) {
- pathconfig->prefix = _PyMem_RawWcsdup(prefix);
- if (pathconfig->prefix == NULL) {
- return _PyStatus_NO_MEMORY();
- }
- }
- if (pathconfig->exec_prefix == NULL) {
- pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix);
- if (pathconfig->exec_prefix == NULL) {
- return _PyStatus_NO_MEMORY();
- }
- }
-
- return _PyStatus_OK();
-}
-
-
-static PyStatus
-calculate_init(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
- const PyConfig *config)
+char *
+Py_GetPath(void)
{
- calculate->home = pathconfig->home;
- calculate->path_env = _wgetenv(L"PATH");
-
- calculate->dll_path = _Py_GetDLLPath();
- if (calculate->dll_path == NULL) {
- return _PyStatus_NO_MEMORY();
- }
-
- calculate->pythonpath_env = config->pythonpath_env;
-
- return _PyStatus_OK();
+ if (!module_search_path)
+ calculate_path();
+ return module_search_path;
}
-
-static void
-calculate_free(PyCalculatePath *calculate)
+char *
+Py_GetPrefix(void)
{
- PyMem_RawFree(calculate->machine_path);
- PyMem_RawFree(calculate->user_path);
- PyMem_RawFree(calculate->dll_path);
+ if (!module_search_path)
+ calculate_path();
+ return prefix;
}
-
-/* Calculate the Python path configuration.
-
- Inputs:
-
- - PyConfig.pythonpath_env: PYTHONPATH environment variable
- - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable
- - DLL path: _Py_GetDLLPath()
- - PATH environment variable
- - __PYVENV_LAUNCHER__ environment variable
- - GetModuleFileNameW(NULL): fully qualified path of the executable file of
- the current process
- - ._pth configuration file
- - pyvenv.cfg configuration file
- - Registry key "Software\Python\PythonCore\X.Y\PythonPath"
- of HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE where X.Y is the Python
- version.
-
- Outputs, 'pathconfig' fields:
-
- - base_executable
- - program_full_path
- - module_search_path
- - prefix
- - exec_prefix
- - isolated
- - site_import
-
- If a field is already set (non NULL), it is left unchanged. */
-PyStatus
-_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
+char *
+Py_GetExecPrefix(void)
{
- PyStatus status;
- PyCalculatePath calculate;
- memset(&calculate, 0, sizeof(calculate));
-
- status = calculate_init(&calculate, pathconfig, config);
- if (_PyStatus_EXCEPTION(status)) {
- goto done;
- }
-
- status = calculate_path(&calculate, pathconfig);
-
-done:
- calculate_free(&calculate);
- return status;
+ return Py_GetPrefix();
}
-
-/* Load python3.dll before loading any extension module that might refer
- to it. That way, we can be sure that always the python3.dll corresponding
- to this python DLL is loaded, not a python3.dll that might be on the path
- by chance.
- Return whether the DLL was found.
-*/
-static int python3_checked = 0;
-static HANDLE hPython3;
-int
-_Py_CheckPython3(void)
+char *
+Py_GetProgramFullPath(void)
{
- wchar_t py3path[MAXPATHLEN+1];
- wchar_t *s;
- if (python3_checked) {
- return hPython3 != NULL;
- }
- python3_checked = 1;
-
- /* If there is a python3.dll next to the python3y.dll,
- assume this is a build tree; use that DLL */
- if (_Py_dll_path != NULL) {
- wcscpy(py3path, _Py_dll_path);
- }
- else {
- wcscpy(py3path, L"");
- }
- s = wcsrchr(py3path, L'\\');
- if (!s) {
- s = py3path;
- }
- wcscpy(s, L"\\python3.dll");
- hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (hPython3 != NULL) {
- return 1;
- }
-
- /* Check sys.prefix\DLLs\python3.dll */
- wcscpy(py3path, Py_GetPrefix());
- wcscat(py3path, L"\\DLLs\\python3.dll");
- hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- return hPython3 != NULL;
+ if (!module_search_path)
+ calculate_path();
+ return progpath;
}