wchar_t* _Py_wgetcwd(wchar_t *buf, size_t size) { #ifdef MS_WINDOWS int isize = (int)Py_MIN(size, INT_MAX); return _wgetcwd(buf, isize); #else char fname[MAXPATHLEN]; wchar_t *wname; size_t len; if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL) return NULL; wname = _Py_char2wchar(fname, &len); if (wname == NULL) return NULL; if (size <= len) { PyMem_RawFree(wname); return NULL; } wcsncpy(buf, wname, size); PyMem_RawFree(wname); return buf; #endif }
wchar_t* _Py_wrealpath(const wchar_t *path, wchar_t *resolved_path, size_t resolved_path_size) { char *cpath; char cresolved_path[MAXPATHLEN]; wchar_t *wresolved_path; char *res; size_t r; cpath = _Py_wchar2char(path, NULL); if (cpath == NULL) { errno = EINVAL; return NULL; } res = realpath(cpath, cresolved_path); PyMem_Free(cpath); if (res == NULL) return NULL; wresolved_path = _Py_char2wchar(cresolved_path, &r); if (wresolved_path == NULL) { errno = EINVAL; return NULL; } if (resolved_path_size <= r) { PyMem_RawFree(wresolved_path); errno = EINVAL; return NULL; } wcsncpy(resolved_path, wresolved_path, resolved_path_size); PyMem_RawFree(wresolved_path); return resolved_path; }
int nacl_main(int argc, char **argv) { if (nacl_startup_untar(argv[0], DATA_FILE, "/")) return -1; wchar_t **argv_copy; /* We need a second copy, as Python might modify the first one. */ wchar_t **argv_copy2; int i, res; char *oldloc; #ifdef __FreeBSD__ fp_except_t m; #endif argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); return 1; } /* 754 requires that FP exceptions run in "no stop" mode by default, * and until C vendors implement C99's ways to control FP exceptions, * Python requires non-stop mode. Alas, some platforms enable FP * exceptions by default. Here we disable them. */ #ifdef __FreeBSD__ m = fpgetmask(); fpsetmask(m & ~FP_X_OFL); #endif oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); return 1; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = _Py_char2wchar(argv[i], NULL); if (!argv_copy[i]) { PyMem_RawFree(oldloc); fprintf(stderr, "Fatal Python error: " "unable to decode the command line argument #%i\n", i + 1); return 1; } argv_copy2[i] = argv_copy[i]; } argv_copy2[argc] = argv_copy[argc] = NULL; setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); res = Py_Main(argc, argv_copy); for (i = 0; i < argc; i++) { PyMem_RawFree(argv_copy2[i]); } PyMem_RawFree(argv_copy); PyMem_RawFree(argv_copy2); return res; }
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ static int search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix) { size_t n; wchar_t *vpath; /* If PYTHONHOME is set, we believe it unconditionally */ if (home) { wchar_t *delim; wcsncpy(prefix, home, MAXPATHLEN); delim = wcschr(prefix, DELIM); if (delim) *delim = L'\0'; joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); return 1; } /* Check to see if argv[0] is in the build directory */ wcscpy(prefix, argv0_path); joinpath(prefix, L"Modules/Setup"); if (isfile(prefix)) { /* Check VPATH to see if argv0_path is in the build directory. */ vpath = _Py_char2wchar(VPATH, NULL); if (vpath != NULL) { wcscpy(prefix, argv0_path); joinpath(prefix, vpath); PyMem_Free(vpath); joinpath(prefix, L"Lib"); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return -1; } } /* Search from argv0_path, until root is found */ copy_absolute(prefix, argv0_path, MAXPATHLEN+1); do { n = wcslen(prefix); joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return 1; prefix[n] = L'\0'; reduce(prefix); } while (prefix[0]); /* Look at configure's PREFIX */ wcsncpy(prefix, _prefix, MAXPATHLEN); joinpath(prefix, lib_python); joinpath(prefix, LANDMARK); if (ismodule(prefix)) return 1; /* Fail */ return 0; }
int _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz) { char *cpath; char cbuf[MAXPATHLEN]; wchar_t *wbuf; int res; size_t r1; cpath = _Py_wchar2char(path, NULL); if (cpath == NULL) { errno = EINVAL; return -1; } res = (int)readlink(cpath, cbuf, Py_ARRAY_LENGTH(cbuf)); PyMem_Free(cpath); if (res == -1) return -1; if (res == Py_ARRAY_LENGTH(cbuf)) { errno = EINVAL; return -1; } cbuf[res] = '\0'; /* buf will be null terminated */ wbuf = _Py_char2wchar(cbuf, &r1); if (wbuf == NULL) { errno = EINVAL; return -1; } if (bufsiz <= r1) { PyMem_RawFree(wbuf); errno = EINVAL; return -1; } wcsncpy(buf, wbuf, bufsiz); PyMem_RawFree(wbuf); return (int)r1; }
wchar_t* _Py_wgetcwd(wchar_t *buf, size_t size) { #ifdef MS_WINDOWS return _wgetcwd(buf, size); #else char fname[PATH_MAX]; wchar_t *wname; size_t len; if (getcwd(fname, PATH_MAX) == NULL) return NULL; wname = _Py_char2wchar(fname, &len); if (wname == NULL) return NULL; if (size <= len) { PyMem_Free(wname); return NULL; } wcsncpy(buf, wname, size); PyMem_Free(wname); return buf; #endif }
static void calculate_path(void) { extern wchar_t *Py_GetProgramName(void); static wchar_t delimiter[2] = {DELIM, '\0'}; static wchar_t separator[2] = {SEP, '\0'}; char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */ wchar_t rtpypath[MAXPATHLEN+1]; wchar_t *home = Py_GetPythonHome(); char *_path = getenv("PATH"); wchar_t *path_buffer = NULL; wchar_t *path = NULL; wchar_t *prog = Py_GetProgramName(); wchar_t argv0_path[MAXPATHLEN+1]; wchar_t zip_path[MAXPATHLEN+1]; int pfound, efound; /* 1 if found; -1 if found build directory */ wchar_t *buf; size_t bufsz; size_t prefixsz; wchar_t *defpath; #ifdef WITH_NEXT_FRAMEWORK NSModule pythonModule; #endif #ifdef __APPLE__ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 uint32_t nsexeclength = MAXPATHLEN; #else unsigned long nsexeclength = MAXPATHLEN; #endif char execpath[MAXPATHLEN+1]; #endif wchar_t *_pythonpath, *_prefix, *_exec_prefix; _pythonpath = _Py_char2wchar(PYTHONPATH, NULL); _prefix = _Py_char2wchar(PREFIX, NULL); _exec_prefix = _Py_char2wchar(EXEC_PREFIX, NULL); if (!_pythonpath || !_prefix || !_exec_prefix) { Py_FatalError( "Unable to decode path variables in getpath.c: " "memory error"); } if (_path) { path_buffer = _Py_char2wchar(_path, NULL); path = path_buffer; } /* 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. */ if (wcschr(prog, SEP)) wcsncpy(progpath, prog, MAXPATHLEN); #ifdef __APPLE__ /* On Mac OS X, if a script uses an interpreter of the form * "#!/opt/python2.3/bin/python", the kernel only passes "python" * as argv[0], which falls through to the $PATH search below. * If /opt/python2.3/bin isn't in your path, or is near the end, * this algorithm may incorrectly find /usr/bin/python. To work * around this, we can use _NSGetExecutablePath to get a better * hint of what the intended interpreter was, although this * will fail if a relative path was used. but in that case, * absolutize() should help us out below */ else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) { size_t r = mbstowcs(progpath, execpath, MAXPATHLEN+1); if (r == (size_t)-1 || r > MAXPATHLEN) { /* Could not convert execpath, or it's too long. */ progpath[0] = '\0'; } } #endif /* __APPLE__ */ else if (path) { while (1) { wchar_t *delim = wcschr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; wcsncpy(progpath, path, len); *(progpath + len) = '\0'; } else wcsncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = L'\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if (path_buffer != NULL) PyMem_Free(path_buffer); if (progpath[0] != SEP && progpath[0] != '\0') absolutize(progpath); wcsncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; #ifdef WITH_NEXT_FRAMEWORK /* 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... */ pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); /* Use dylib functions to find out where the framework was loaded from */ buf = (wchar_t *)NSLibraryNameForModule(pythonModule); if (buf != NULL) { /* We're in a framework. */ /* See if we might be in the build directory. The framework in the ** build directory is incomplete, it only has the .dylib and a few ** needed symlinks, it doesn't have the Lib directories and such. ** If we're running with the framework from the build directory we must ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ wcsncpy(argv0_path, buf, MAXPATHLEN); reduce(argv0_path); joinpath(argv0_path, lib_python); joinpath(argv0_path, LANDMARK); if (!ismodule(argv0_path)) { /* We are in the build directory so use the name of the executable - we know that the absolute path is passed */ wcsncpy(argv0_path, progpath, MAXPATHLEN); } else { /* Use the location of the library as the progpath */ wcsncpy(argv0_path, buf, MAXPATHLEN); } } #endif #if HAVE_READLINK { wchar_t tmpbuffer[MAXPATHLEN+1]; int linklen = _Py_wreadlink(progpath, tmpbuffer, MAXPATHLEN); while (linklen != -1) { if (tmpbuffer[0] == SEP) /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ wcsncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { /* Interpret relative to progpath */ reduce(argv0_path); joinpath(argv0_path, tmpbuffer); } linklen = _Py_wreadlink(argv0_path, tmpbuffer, MAXPATHLEN); } } #endif /* HAVE_READLINK */ reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ if (!(pfound = search_for_prefix(argv0_path, home, _prefix))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); wcsncpy(prefix, _prefix, MAXPATHLEN); joinpath(prefix, lib_python); } else reduce(prefix); wcsncpy(zip_path, prefix, MAXPATHLEN); zip_path[MAXPATHLEN] = L'\0'; if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */ reduce(zip_path); reduce(zip_path); } else wcsncpy(zip_path, _prefix, MAXPATHLEN); joinpath(zip_path, L"lib/python00.zip"); bufsz = wcslen(zip_path); /* Replace "00" with version */ zip_path[bufsz - 6] = VERSION[0]; zip_path[bufsz - 5] = VERSION[2]; if (!(efound = search_for_exec_prefix(argv0_path, home, _exec_prefix))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); joinpath(exec_prefix, L"lib/lib-dynload"); } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ if ((!pfound || !efound) && !Py_FrozenFlag) fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); /* Calculate size of return buffer. */ bufsz = 0; if (_rtpypath) { size_t s = mbstowcs(rtpypath, _rtpypath, sizeof(rtpypath)/sizeof(wchar_t)); if (s == (size_t)-1 || s >=sizeof(rtpypath)) /* XXX deal with errors more gracefully */ _rtpypath = NULL; if (_rtpypath) bufsz += wcslen(rtpypath) + 1; } defpath = _pythonpath; prefixsz = wcslen(prefix) + 1; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += wcslen(defpath) + 1; break; } defpath = delim + 1; } bufsz += wcslen(zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = (wchar_t *)PyMem_Malloc(bufsz*sizeof(wchar_t)); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = L"" PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (_rtpypath) { wcscpy(buf, rtpypath); wcscat(buf, delimiter); } else buf[0] = '\0'; /* Next is the default zip path */ wcscat(buf, zip_path); wcscat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = _pythonpath; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) { wcscat(buf, prefix); wcscat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = wcslen(buf) + len; wcsncat(buf, defpath, len); *(buf + end) = '\0'; } else { wcscat(buf, defpath); break; } defpath = delim + 1; } wcscat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ wcscat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ if (pfound > 0) { reduce(prefix); reduce(prefix); /* The prefix is the root directory, but reduce() chopped * off the "/". */ if (!prefix[0]) wcscpy(prefix, separator); } else wcsncpy(prefix, _prefix, MAXPATHLEN); if (efound > 0) { reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); if (!exec_prefix[0]) wcscpy(exec_prefix, separator); } else wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); PyMem_Free(_pythonpath); PyMem_Free(_prefix); PyMem_Free(_exec_prefix); }
int Py_FrozenMain(int argc, char **argv) { char *p; int i, n, sts = 1; int inspect = 0; int unbuffered = 0; char *oldloc = NULL; wchar_t **argv_copy = NULL; /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); goto error; } Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); goto error; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = _Py_char2wchar(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", i + 1); argc = i; goto error; } } setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); oldloc = NULL; #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ Py_SetProgramName(argv_copy[0]); Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv_copy); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif Py_Finalize(); error: PyMem_RawFree(argv_copy); if (argv_copy2) { for (i = 0; i < argc; i++) PyMem_RawFree(argv_copy2[i]); PyMem_RawFree(argv_copy2); } PyMem_RawFree(oldloc); return sts; }