diff options
Diffstat (limited to 'Python/pathconfig.c')
-rw-r--r-- | Python/pathconfig.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/Python/pathconfig.c b/Python/pathconfig.c index 53ddfc9..b17ae82 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -261,6 +261,104 @@ Py_GetProgramName(void) } +#define _HAVE_SCRIPT_ARGUMENT(argc, argv) \ + (argc > 0 && argv0 != NULL && \ + wcscmp(argv0, L"-c") != 0 && wcscmp(argv0, L"-m") != 0) + +/* Compute argv[0] which will be prepended to sys.argv */ +PyObject* +_PyPathConfig_ComputeArgv0(int argc, wchar_t **argv) +{ + wchar_t *argv0; + wchar_t *p = NULL; + Py_ssize_t n = 0; +#ifdef HAVE_READLINK + wchar_t link[MAXPATHLEN+1]; + wchar_t argv0copy[2*MAXPATHLEN+1]; + int nr = 0; +#endif +#if defined(HAVE_REALPATH) + wchar_t fullpath[MAXPATHLEN]; +#elif defined(MS_WINDOWS) + wchar_t fullpath[MAX_PATH]; +#endif + + + argv0 = argv[0]; + +#ifdef HAVE_READLINK + if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) + nr = _Py_wreadlink(argv0, link, MAXPATHLEN); + if (nr > 0) { + /* It's a symlink */ + link[nr] = '\0'; + if (link[0] == SEP) + argv0 = link; /* Link to absolute path */ + else if (wcschr(link, SEP) == NULL) + ; /* Link without path */ + else { + /* Must join(dirname(argv0), link) */ + wchar_t *q = wcsrchr(argv0, SEP); + if (q == NULL) + argv0 = link; /* argv0 without path */ + else { + /* Must make a copy, argv0copy has room for 2 * MAXPATHLEN */ + wcsncpy(argv0copy, argv0, MAXPATHLEN); + q = wcsrchr(argv0copy, SEP); + wcsncpy(q+1, link, MAXPATHLEN); + q[MAXPATHLEN + 1] = L'\0'; + argv0 = argv0copy; + } + } + } +#endif /* HAVE_READLINK */ + +#if SEP == '\\' + /* Special case for Microsoft filename syntax */ + if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) { + wchar_t *q; +#if defined(MS_WINDOWS) + /* Replace the first element in argv with the full path. */ + wchar_t *ptemp; + if (GetFullPathNameW(argv0, + Py_ARRAY_LENGTH(fullpath), + fullpath, + &ptemp)) { + argv0 = fullpath; + } +#endif + p = wcsrchr(argv0, SEP); + /* Test for alternate separator */ + q = wcsrchr(p ? p : argv0, '/'); + if (q != NULL) + p = q; + if (p != NULL) { + n = p + 1 - argv0; + if (n > 1 && p[-1] != ':') + n--; /* Drop trailing separator */ + } + } +#else /* All other filename syntaxes */ + if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) { +#if defined(HAVE_REALPATH) + if (_Py_wrealpath(argv0, fullpath, Py_ARRAY_LENGTH(fullpath))) { + argv0 = fullpath; + } +#endif + p = wcsrchr(argv0, SEP); + } + if (p != NULL) { + n = p + 1 - argv0; +#if SEP == '/' /* Special case for Unix filename syntax */ + if (n > 1) + n--; /* Drop trailing separator */ +#endif /* Unix */ + } +#endif /* All others */ + + return PyUnicode_FromWideChar(argv0, n); +} + #ifdef __cplusplus } #endif |