summaryrefslogtreecommitdiffstats
path: root/Python/pathconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pathconfig.c')
-rw-r--r--Python/pathconfig.c98
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