123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957 |
- #define PYTHONPATH ":"
- /* Return the initial module search path. */
- #include "Python.h"
- #include "marshal.h" // PyMarshal_ReadObjectFromString
- #include "osdefs.h" // DELIM
- #include "pycore_initconfig.h"
- #include "pycore_fileutils.h"
- #include "pycore_pathconfig.h"
- #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
- #include <wchar.h>
- #ifdef MS_WINDOWS
- # include <windows.h> // GetFullPathNameW(), MAX_PATH
- # include <pathcch.h>
- #endif
- #ifdef __APPLE__
- # include <mach-o/dyld.h>
- #endif
- /* Reference the precompiled getpath.py */
- #include "../Python/frozen_modules/getpath.h"
- #if (!defined(PREFIX) || !defined(EXEC_PREFIX) \
- || !defined(VERSION) || !defined(VPATH) \
- || !defined(PLATLIBDIR))
- #error "PREFIX, EXEC_PREFIX, VERSION, VPATH and PLATLIBDIR macros must be defined"
- #endif
- #if !defined(PYTHONPATH)
- #define PYTHONPATH NULL
- #endif
- #if !defined(PYDEBUGEXT)
- #define PYDEBUGEXT NULL
- #endif
- #if !defined(PYWINVER)
- #ifdef MS_DLL_ID
- #define PYWINVER MS_DLL_ID
- #else
- #define PYWINVER NULL
- #endif
- #endif
- #if !defined(EXE_SUFFIX)
- #if defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(__MINGW32__)
- #define EXE_SUFFIX L".exe"
- #else
- #define EXE_SUFFIX NULL
- #endif
- #endif
- /* HELPER FUNCTIONS for getpath.py */
- static PyObject *
- getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *r = NULL;
- PyObject *pathobj;
- wchar_t *path;
- if (!PyArg_ParseTuple(args, "U", &pathobj)) {
- return NULL;
- }
- Py_ssize_t len;
- path = PyUnicode_AsWideCharString(pathobj, &len);
- if (path) {
- wchar_t *abs;
- if (_Py_abspath((const wchar_t *)_Py_normpath(path, -1), &abs) == 0 && abs) {
- r = PyUnicode_FromWideChar(abs, -1);
- PyMem_RawFree((void *)abs);
- } else {
- PyErr_SetString(PyExc_OSError, "failed to make path absolute");
- }
- PyMem_Free((void *)path);
- }
- return r;
- }
- static PyObject *
- getpath_basename(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *path;
- if (!PyArg_ParseTuple(args, "U", &path)) {
- return NULL;
- }
- Py_ssize_t end = PyUnicode_GET_LENGTH(path);
- Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1);
- if (pos < 0) {
- return Py_NewRef(path);
- }
- return PyUnicode_Substring(path, pos + 1, end);
- }
- static PyObject *
- getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *path;
- if (!PyArg_ParseTuple(args, "U", &path)) {
- return NULL;
- }
- Py_ssize_t end = PyUnicode_GET_LENGTH(path);
- Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1);
- if (pos < 0) {
- return PyUnicode_FromStringAndSize(NULL, 0);
- }
- return PyUnicode_Substring(path, 0, pos);
- }
- static PyObject *
- getpath_isabs(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *r = NULL;
- PyObject *pathobj;
- const wchar_t *path;
- if (!PyArg_ParseTuple(args, "U", &pathobj)) {
- return NULL;
- }
- path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (path) {
- r = _Py_isabs(path) ? Py_True : Py_False;
- PyMem_Free((void *)path);
- }
- return Py_XNewRef(r);
- }
- static PyObject *
- getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *r = NULL;
- PyObject *pathobj;
- PyObject *suffixobj;
- const wchar_t *path;
- const wchar_t *suffix;
- if (!PyArg_ParseTuple(args, "UU", &pathobj, &suffixobj)) {
- return NULL;
- }
- Py_ssize_t len, suffixLen;
- path = PyUnicode_AsWideCharString(pathobj, &len);
- if (path) {
- suffix = PyUnicode_AsWideCharString(suffixobj, &suffixLen);
- if (suffix) {
- if (suffixLen > len ||
- #ifdef MS_WINDOWS
- wcsicmp(&path[len - suffixLen], suffix) != 0
- #else
- wcscmp(&path[len - suffixLen], suffix) != 0
- #endif
- ) {
- r = Py_NewRef(Py_False);
- } else {
- r = Py_NewRef(Py_True);
- }
- PyMem_Free((void *)suffix);
- }
- PyMem_Free((void *)path);
- }
- return r;
- }
- static PyObject *
- getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *r = NULL;
- PyObject *pathobj;
- const wchar_t *path;
- if (!PyArg_ParseTuple(args, "U", &pathobj)) {
- return NULL;
- }
- path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (path) {
- #ifdef MS_WINDOWS
- DWORD attr = GetFileAttributesW(path);
- r = (attr != INVALID_FILE_ATTRIBUTES) &&
- (attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False;
- #else
- struct stat st;
- r = (_Py_wstat(path, &st) == 0) && S_ISDIR(st.st_mode) ? Py_True : Py_False;
- #endif
- PyMem_Free((void *)path);
- }
- return Py_XNewRef(r);
- }
- static PyObject *
- getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *r = NULL;
- PyObject *pathobj;
- const wchar_t *path;
- if (!PyArg_ParseTuple(args, "U", &pathobj)) {
- return NULL;
- }
- path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (path) {
- #ifdef MS_WINDOWS
- DWORD attr = GetFileAttributesW(path);
- r = (attr != INVALID_FILE_ATTRIBUTES) &&
- !(attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False;
- #else
- struct stat st;
- r = (_Py_wstat(path, &st) == 0) && S_ISREG(st.st_mode) ? Py_True : Py_False;
- #endif
- PyMem_Free((void *)path);
- }
- return Py_XNewRef(r);
- }
- static PyObject *
- getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *r = NULL;
- PyObject *pathobj;
- const wchar_t *path;
- Py_ssize_t cchPath;
- if (!PyArg_ParseTuple(args, "U", &pathobj)) {
- return NULL;
- }
- path = PyUnicode_AsWideCharString(pathobj, &cchPath);
- if (path) {
- #ifdef MS_WINDOWS
- DWORD attr = GetFileAttributesW(path);
- r = (attr != INVALID_FILE_ATTRIBUTES) &&
- !(attr & FILE_ATTRIBUTE_DIRECTORY) &&
- (cchPath >= 4) &&
- (CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL)
- ? Py_True : Py_False;
- #else
- struct stat st;
- r = (_Py_wstat(path, &st) == 0) &&
- S_ISREG(st.st_mode) &&
- (st.st_mode & 0111)
- ? Py_True : Py_False;
- #endif
- PyMem_Free((void *)path);
- }
- return Py_XNewRef(r);
- }
- static PyObject *
- getpath_joinpath(PyObject *Py_UNUSED(self), PyObject *args)
- {
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_TypeError, "requires tuple of arguments");
- return NULL;
- }
- Py_ssize_t n = PyTuple_GET_SIZE(args);
- if (n == 0) {
- return PyUnicode_FromStringAndSize(NULL, 0);
- }
- /* Convert all parts to wchar and accumulate max final length */
- wchar_t **parts = (wchar_t **)PyMem_Malloc(n * sizeof(wchar_t *));
- if (parts == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- memset(parts, 0, n * sizeof(wchar_t *));
- Py_ssize_t cchFinal = 0;
- Py_ssize_t first = 0;
- for (Py_ssize_t i = 0; i < n; ++i) {
- PyObject *s = PyTuple_GET_ITEM(args, i);
- Py_ssize_t cch;
- if (s == Py_None) {
- cch = 0;
- } else if (PyUnicode_Check(s)) {
- parts[i] = PyUnicode_AsWideCharString(s, &cch);
- if (!parts[i]) {
- cchFinal = -1;
- break;
- }
- if (_Py_isabs(parts[i])) {
- first = i;
- }
- } else {
- PyErr_SetString(PyExc_TypeError, "all arguments to joinpath() must be str or None");
- cchFinal = -1;
- break;
- }
- cchFinal += cch + 1;
- }
- wchar_t *final = cchFinal > 0 ? (wchar_t *)PyMem_Malloc(cchFinal * sizeof(wchar_t)) : NULL;
- if (!final) {
- for (Py_ssize_t i = 0; i < n; ++i) {
- PyMem_Free(parts[i]);
- }
- PyMem_Free(parts);
- if (cchFinal) {
- PyErr_NoMemory();
- return NULL;
- }
- return PyUnicode_FromStringAndSize(NULL, 0);
- }
- final[0] = '\0';
- /* Now join all the paths. The final result should be shorter than the buffer */
- for (Py_ssize_t i = 0; i < n; ++i) {
- if (!parts[i]) {
- continue;
- }
- if (i >= first && final) {
- if (!final[0]) {
- /* final is definitely long enough to fit any individual part */
- wcscpy(final, parts[i]);
- } else if (_Py_add_relfile(final, parts[i], cchFinal) < 0) {
- /* if we fail, keep iterating to free memory, but stop adding parts */
- PyMem_Free(final);
- final = NULL;
- }
- }
- PyMem_Free(parts[i]);
- }
- PyMem_Free(parts);
- if (!final) {
- PyErr_SetString(PyExc_SystemError, "failed to join paths");
- return NULL;
- }
- PyObject *r = PyUnicode_FromWideChar(_Py_normpath(final, -1), -1);
- PyMem_Free(final);
- return r;
- }
- static PyObject *
- getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *r = NULL;
- PyObject *pathobj;
- const wchar_t *path;
- if (!PyArg_ParseTuple(args, "U", &pathobj)) {
- return NULL;
- }
- path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (!path) {
- return NULL;
- }
- FILE *fp = _Py_wfopen(path, L"rb");
- if (!fp) {
- PyErr_SetFromErrno(PyExc_OSError);
- PyMem_Free((void *)path);
- return NULL;
- }
- PyMem_Free((void *)path);
- r = PyList_New(0);
- if (!r) {
- fclose(fp);
- return NULL;
- }
- const size_t MAX_FILE = 32 * 1024;
- char *buffer = (char *)PyMem_Malloc(MAX_FILE);
- if (!buffer) {
- Py_DECREF(r);
- fclose(fp);
- return NULL;
- }
- size_t cb = fread(buffer, 1, MAX_FILE, fp);
- fclose(fp);
- if (!cb) {
- return r;
- }
- if (cb >= MAX_FILE) {
- Py_DECREF(r);
- PyErr_SetString(PyExc_MemoryError,
- "cannot read file larger than 32KB during initialization");
- return NULL;
- }
- buffer[cb] = '\0';
- size_t len;
- wchar_t *wbuffer = _Py_DecodeUTF8_surrogateescape(buffer, cb, &len);
- PyMem_Free((void *)buffer);
- if (!wbuffer) {
- Py_DECREF(r);
- PyErr_NoMemory();
- return NULL;
- }
- wchar_t *p1 = wbuffer;
- wchar_t *p2 = p1;
- while ((p2 = wcschr(p1, L'\n')) != NULL) {
- Py_ssize_t cb = p2 - p1;
- while (cb >= 0 && (p1[cb] == L'\n' || p1[cb] == L'\r')) {
- --cb;
- }
- PyObject *u = PyUnicode_FromWideChar(p1, cb >= 0 ? cb + 1 : 0);
- if (!u || PyList_Append(r, u) < 0) {
- Py_XDECREF(u);
- Py_CLEAR(r);
- break;
- }
- Py_DECREF(u);
- p1 = p2 + 1;
- }
- if (r && p1 && *p1) {
- PyObject *u = PyUnicode_FromWideChar(p1, -1);
- if (!u || PyList_Append(r, u) < 0) {
- Py_CLEAR(r);
- }
- Py_XDECREF(u);
- }
- PyMem_RawFree(wbuffer);
- return r;
- }
- static PyObject *
- getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args)
- {
- PyObject *pathobj;
- if (!PyArg_ParseTuple(args, "U", &pathobj)) {
- return NULL;
- }
- #if defined(HAVE_READLINK)
- /* This readlink calculation only resolves a symlinked file, and
- does not resolve any path segments. This is consistent with
- prior releases, however, the realpath implementation below is
- potentially correct in more cases. */
- PyObject *r = NULL;
- int nlink = 0;
- wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (!path) {
- goto done;
- }
- wchar_t *path2 = _PyMem_RawWcsdup(path);
- PyMem_Free((void *)path);
- path = path2;
- while (path) {
- wchar_t resolved[MAXPATHLEN + 1];
- int linklen = _Py_wreadlink(path, resolved, Py_ARRAY_LENGTH(resolved));
- if (linklen == -1) {
- r = PyUnicode_FromWideChar(path, -1);
- break;
- }
- if (_Py_isabs(resolved)) {
- PyMem_RawFree((void *)path);
- path = _PyMem_RawWcsdup(resolved);
- } else {
- wchar_t *s = wcsrchr(path, SEP);
- if (s) {
- *s = L'\0';
- }
- path2 = _Py_join_relfile(path, resolved);
- if (path2) {
- path2 = _Py_normpath(path2, -1);
- }
- PyMem_RawFree((void *)path);
- path = path2;
- }
- nlink++;
- /* 40 is the Linux kernel 4.2 limit */
- if (nlink >= 40) {
- PyErr_SetString(PyExc_OSError, "maximum number of symbolic links reached");
- break;
- }
- }
- if (!path) {
- PyErr_NoMemory();
- }
- done:
- PyMem_RawFree((void *)path);
- return r;
- #elif defined(HAVE_REALPATH)
- PyObject *r = NULL;
- struct stat st;
- const char *narrow = NULL;
- wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (!path) {
- goto done;
- }
- narrow = Py_EncodeLocale(path, NULL);
- if (!narrow) {
- PyErr_NoMemory();
- goto done;
- }
- if (lstat(narrow, &st)) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto done;
- }
- if (!S_ISLNK(st.st_mode)) {
- r = Py_NewRef(pathobj);
- goto done;
- }
- wchar_t resolved[MAXPATHLEN+1];
- if (_Py_wrealpath(path, resolved, MAXPATHLEN) == NULL) {
- PyErr_SetFromErrno(PyExc_OSError);
- } else {
- r = PyUnicode_FromWideChar(resolved, -1);
- }
- done:
- PyMem_Free((void *)path);
- PyMem_Free((void *)narrow);
- return r;
- #endif
- return Py_NewRef(pathobj);
- }
- static PyMethodDef getpath_methods[] = {
- {"abspath", getpath_abspath, METH_VARARGS, NULL},
- {"basename", getpath_basename, METH_VARARGS, NULL},
- {"dirname", getpath_dirname, METH_VARARGS, NULL},
- {"hassuffix", getpath_hassuffix, METH_VARARGS, NULL},
- {"isabs", getpath_isabs, METH_VARARGS, NULL},
- {"isdir", getpath_isdir, METH_VARARGS, NULL},
- {"isfile", getpath_isfile, METH_VARARGS, NULL},
- {"isxfile", getpath_isxfile, METH_VARARGS, NULL},
- {"joinpath", getpath_joinpath, METH_VARARGS, NULL},
- {"readlines", getpath_readlines, METH_VARARGS, NULL},
- {"realpath", getpath_realpath, METH_VARARGS, NULL},
- {NULL, NULL, 0, NULL}
- };
- /* Two implementations of warn() to use depending on whether warnings
- are enabled or not. */
- static PyObject *
- getpath_warn(PyObject *Py_UNUSED(self), PyObject *args)
- {
- PyObject *msgobj;
- if (!PyArg_ParseTuple(args, "U", &msgobj)) {
- return NULL;
- }
- fprintf(stderr, "%s\n", PyUnicode_AsUTF8(msgobj));
- Py_RETURN_NONE;
- }
- static PyObject *
- getpath_nowarn(PyObject *Py_UNUSED(self), PyObject *args)
- {
- Py_RETURN_NONE;
- }
- static PyMethodDef getpath_warn_method = {"warn", getpath_warn, METH_VARARGS, NULL};
- static PyMethodDef getpath_nowarn_method = {"warn", getpath_nowarn, METH_VARARGS, NULL};
- /* Add the helper functions to the dict */
- static int
- funcs_to_dict(PyObject *dict, int warnings)
- {
- for (PyMethodDef *m = getpath_methods; m->ml_name; ++m) {
- PyObject *f = PyCFunction_NewEx(m, NULL, NULL);
- if (!f) {
- return 0;
- }
- if (PyDict_SetItemString(dict, m->ml_name, f) < 0) {
- Py_DECREF(f);
- return 0;
- }
- Py_DECREF(f);
- }
- PyMethodDef *m2 = warnings ? &getpath_warn_method : &getpath_nowarn_method;
- PyObject *f = PyCFunction_NewEx(m2, NULL, NULL);
- if (!f) {
- return 0;
- }
- if (PyDict_SetItemString(dict, m2->ml_name, f) < 0) {
- Py_DECREF(f);
- return 0;
- }
- Py_DECREF(f);
- return 1;
- }
- /* Add a wide-character string constant to the dict */
- static int
- wchar_to_dict(PyObject *dict, const char *key, const wchar_t *s)
- {
- PyObject *u;
- int r;
- if (s && s[0]) {
- u = PyUnicode_FromWideChar(s, -1);
- if (!u) {
- return 0;
- }
- } else {
- u = Py_NewRef(Py_None);
- }
- r = PyDict_SetItemString(dict, key, u) == 0;
- Py_DECREF(u);
- return r;
- }
- /* Add a narrow string constant to the dict, using default locale decoding */
- static int
- decode_to_dict(PyObject *dict, const char *key, const char *s)
- {
- PyObject *u = NULL;
- int r;
- if (s && s[0]) {
- size_t len;
- const wchar_t *w = Py_DecodeLocale(s, &len);
- if (w) {
- u = PyUnicode_FromWideChar(w, len);
- PyMem_RawFree((void *)w);
- }
- if (!u) {
- return 0;
- }
- } else {
- u = Py_NewRef(Py_None);
- }
- r = PyDict_SetItemString(dict, key, u) == 0;
- Py_DECREF(u);
- return r;
- }
- /* Add an environment variable to the dict, optionally clearing it afterwards */
- static int
- env_to_dict(PyObject *dict, const char *key, int and_clear)
- {
- PyObject *u = NULL;
- int r = 0;
- assert(strncmp(key, "ENV_", 4) == 0);
- assert(strlen(key) < 64);
- #ifdef MS_WINDOWS
- wchar_t wkey[64];
- // Quick convert to wchar_t, since we know key is ASCII
- wchar_t *wp = wkey;
- for (const char *p = &key[4]; *p; ++p) {
- assert(*p < 128);
- *wp++ = *p;
- }
- *wp = L'\0';
- const wchar_t *v = _wgetenv(wkey);
- if (v) {
- u = PyUnicode_FromWideChar(v, -1);
- if (!u) {
- PyErr_Clear();
- }
- }
- #else
- const char *v = getenv(&key[4]);
- if (v) {
- size_t len;
- const wchar_t *w = Py_DecodeLocale(v, &len);
- if (w) {
- u = PyUnicode_FromWideChar(w, len);
- if (!u) {
- PyErr_Clear();
- }
- PyMem_RawFree((void *)w);
- }
- }
- #endif
- if (u) {
- r = PyDict_SetItemString(dict, key, u) == 0;
- Py_DECREF(u);
- } else {
- r = PyDict_SetItemString(dict, key, Py_None) == 0;
- }
- if (r && and_clear) {
- #ifdef MS_WINDOWS
- _wputenv_s(wkey, L"");
- #else
- unsetenv(&key[4]);
- #endif
- }
- return r;
- }
- /* Add an integer constant to the dict */
- static int
- int_to_dict(PyObject *dict, const char *key, int v)
- {
- PyObject *o;
- int r;
- o = PyLong_FromLong(v);
- if (!o) {
- return 0;
- }
- r = PyDict_SetItemString(dict, key, o) == 0;
- Py_DECREF(o);
- return r;
- }
- #ifdef MS_WINDOWS
- static int
- winmodule_to_dict(PyObject *dict, const char *key, HMODULE mod)
- {
- wchar_t *buffer = NULL;
- for (DWORD cch = 256; buffer == NULL && cch < (1024 * 1024); cch *= 2) {
- buffer = (wchar_t*)PyMem_RawMalloc(cch * sizeof(wchar_t));
- if (buffer) {
- if (GetModuleFileNameW(mod, buffer, cch) == cch) {
- PyMem_RawFree(buffer);
- buffer = NULL;
- }
- }
- }
- int r = wchar_to_dict(dict, key, buffer);
- PyMem_RawFree(buffer);
- return r;
- }
- #endif
- /* Add the current executable's path to the dict */
- static int
- progname_to_dict(PyObject *dict, const char *key)
- {
- #ifdef MS_WINDOWS
- return winmodule_to_dict(dict, key, NULL);
- #elif defined(__APPLE__)
- char *path;
- uint32_t pathLen = 256;
- while (pathLen) {
- path = PyMem_RawMalloc((pathLen + 1) * sizeof(char));
- if (!path) {
- return 0;
- }
- if (_NSGetExecutablePath(path, &pathLen) != 0) {
- PyMem_RawFree(path);
- continue;
- }
- // Only keep if the path is absolute
- if (path[0] == SEP) {
- int r = decode_to_dict(dict, key, path);
- PyMem_RawFree(path);
- return r;
- }
- // Fall back and store None
- PyMem_RawFree(path);
- break;
- }
- #endif
- return PyDict_SetItemString(dict, key, Py_None) == 0;
- }
- /* Add the runtime library's path to the dict */
- static int
- library_to_dict(PyObject *dict, const char *key)
- {
- #ifdef MS_WINDOWS
- #ifdef Py_ENABLE_SHARED
- extern HMODULE PyWin_DLLhModule;
- if (PyWin_DLLhModule) {
- return winmodule_to_dict(dict, key, PyWin_DLLhModule);
- }
- #endif
- #elif defined(WITH_NEXT_FRAMEWORK)
- static char modPath[MAXPATHLEN + 1];
- static int modPathInitialized = -1;
- if (modPathInitialized < 0) {
- modPathInitialized = 0;
- /* On Mac OS X we have a special case if we're running from a framework.
- This is because the python home should be set relative to the library,
- which is in the framework, not relative to the executable, which may
- be outside of the framework. Except when we're in the build
- directory... */
- NSSymbol symbol = NSLookupAndBindSymbol("_Py_Initialize");
- if (symbol != NULL) {
- NSModule pythonModule = NSModuleForSymbol(symbol);
- if (pythonModule != NULL) {
- /* Use dylib functions to find out where the framework was loaded from */
- const char *path = NSLibraryNameForModule(pythonModule);
- if (path) {
- strncpy(modPath, path, MAXPATHLEN);
- modPathInitialized = 1;
- }
- }
- }
- }
- if (modPathInitialized > 0) {
- return decode_to_dict(dict, key, modPath);
- }
- #endif
- return PyDict_SetItemString(dict, key, Py_None) == 0;
- }
- PyObject *
- _Py_Get_Getpath_CodeObject(void)
- {
- return PyMarshal_ReadObjectFromString(
- (const char*)_Py_M__getpath, sizeof(_Py_M__getpath));
- }
- /* Perform the actual path calculation.
- When compute_path_config is 0, this only reads any initialised path
- config values into the PyConfig struct. For example, Py_SetHome() or
- Py_SetPath(). The only error should be due to failed memory allocation.
- When compute_path_config is 1, full path calculation is performed.
- The GIL must be held, and there may be filesystem access, side
- effects, and potential unraisable errors that are reported directly
- to stderr.
- Calling this function multiple times on the same PyConfig is only
- safe because already-configured values are not recalculated. To
- actually recalculate paths, you need a clean PyConfig.
- */
- PyStatus
- _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config)
- {
- PyStatus status = _PyPathConfig_ReadGlobal(config);
- if (_PyStatus_EXCEPTION(status) || !compute_path_config) {
- return status;
- }
- if (!_PyThreadState_UncheckedGet()) {
- return PyStatus_Error("cannot calculate path configuration without GIL");
- }
- PyObject *configDict = _PyConfig_AsDict(config);
- if (!configDict) {
- PyErr_Clear();
- return PyStatus_NoMemory();
- }
- PyObject *dict = PyDict_New();
- if (!dict) {
- PyErr_Clear();
- Py_DECREF(configDict);
- return PyStatus_NoMemory();
- }
- if (PyDict_SetItemString(dict, "config", configDict) < 0) {
- PyErr_Clear();
- Py_DECREF(configDict);
- Py_DECREF(dict);
- return PyStatus_NoMemory();
- }
- /* reference now held by dict */
- Py_DECREF(configDict);
- PyObject *co = _Py_Get_Getpath_CodeObject();
- if (!co || !PyCode_Check(co)) {
- PyErr_Clear();
- Py_XDECREF(co);
- Py_DECREF(dict);
- return PyStatus_Error("error reading frozen getpath.py");
- }
- #ifdef MS_WINDOWS
- PyObject *winreg = PyImport_ImportModule("winreg");
- if (!winreg || PyDict_SetItemString(dict, "winreg", winreg) < 0) {
- PyErr_Clear();
- Py_XDECREF(winreg);
- if (PyDict_SetItemString(dict, "winreg", Py_None) < 0) {
- PyErr_Clear();
- Py_DECREF(co);
- Py_DECREF(dict);
- return PyStatus_Error("error importing winreg module");
- }
- } else {
- Py_DECREF(winreg);
- }
- #endif
- if (
- #ifdef MS_WINDOWS
- !decode_to_dict(dict, "os_name", "nt") ||
- #elif defined(__APPLE__)
- !decode_to_dict(dict, "os_name", "darwin") ||
- #else
- !decode_to_dict(dict, "os_name", "posix") ||
- #endif
- #ifdef WITH_NEXT_FRAMEWORK
- !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 1) ||
- #else
- !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 0) ||
- #endif
- !decode_to_dict(dict, "PREFIX", PREFIX) ||
- !decode_to_dict(dict, "EXEC_PREFIX", EXEC_PREFIX) ||
- !decode_to_dict(dict, "PYTHONPATH", PYTHONPATH) ||
- !decode_to_dict(dict, "VPATH", VPATH) ||
- !decode_to_dict(dict, "PLATLIBDIR", PLATLIBDIR) ||
- !decode_to_dict(dict, "PYDEBUGEXT", PYDEBUGEXT) ||
- !int_to_dict(dict, "VERSION_MAJOR", PY_MAJOR_VERSION) ||
- !int_to_dict(dict, "VERSION_MINOR", PY_MINOR_VERSION) ||
- !decode_to_dict(dict, "PYWINVER", PYWINVER) ||
- !wchar_to_dict(dict, "EXE_SUFFIX", EXE_SUFFIX) ||
- !env_to_dict(dict, "ENV_PATH", 0) ||
- !env_to_dict(dict, "ENV_PYTHONHOME", 0) ||
- !env_to_dict(dict, "ENV_PYTHONEXECUTABLE", 0) ||
- !env_to_dict(dict, "ENV___PYVENV_LAUNCHER__", 1) ||
- !progname_to_dict(dict, "real_executable") ||
- !library_to_dict(dict, "library") ||
- !wchar_to_dict(dict, "executable_dir", NULL) ||
- !wchar_to_dict(dict, "py_setpath", _PyPathConfig_GetGlobalModuleSearchPath()) ||
- !funcs_to_dict(dict, config->pathconfig_warnings) ||
- #ifndef MS_WINDOWS
- PyDict_SetItemString(dict, "winreg", Py_None) < 0 ||
- #endif
- PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()) < 0
- ) {
- Py_DECREF(co);
- Py_DECREF(dict);
- _PyErr_WriteUnraisableMsg("error evaluating initial values", NULL);
- return PyStatus_Error("error evaluating initial values");
- }
- PyObject *r = PyEval_EvalCode(co, dict, dict);
- Py_DECREF(co);
- if (!r) {
- Py_DECREF(dict);
- _PyErr_WriteUnraisableMsg("error evaluating path", NULL);
- return PyStatus_Error("error evaluating path");
- }
- Py_DECREF(r);
- #if 0
- PyObject *it = PyObject_GetIter(configDict);
- for (PyObject *k = PyIter_Next(it); k; k = PyIter_Next(it)) {
- if (!strcmp("__builtins__", PyUnicode_AsUTF8(k))) {
- Py_DECREF(k);
- continue;
- }
- fprintf(stderr, "%s = ", PyUnicode_AsUTF8(k));
- PyObject *o = PyDict_GetItem(configDict, k);
- o = PyObject_Repr(o);
- fprintf(stderr, "%s\n", PyUnicode_AsUTF8(o));
- Py_DECREF(o);
- Py_DECREF(k);
- }
- Py_DECREF(it);
- #endif
- if (_PyConfig_FromDict(config, configDict) < 0) {
- _PyErr_WriteUnraisableMsg("reading getpath results", NULL);
- Py_DECREF(dict);
- return PyStatus_Error("error getting getpath results");
- }
- Py_DECREF(dict);
- return _PyStatus_OK();
- }
|