]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Efi/getpath.c
AppPkg/Applications/Python: Get Python startup process fully working for EDK II.
[mirror_edk2.git] / AppPkg / Applications / Python / Efi / getpath.c
CommitLineData
41b152c5 1/** @file\r
2 Return the initial module search path.\r
3\r
4 Search in specified locations for the associated Python libraries.\r
5\r
6 Py_GetPath returns module_search_path.\r
7 Py_GetPrefix returns PREFIX\r
8 Py_GetExec_Prefix returns PREFIX\r
9 Py_GetProgramFullPath returns the full path to the python executable.\r
10\r
11 These are built dynamically so that the proper volume name can be prefixed\r
12 to the paths.\r
13\r
14 For the EDK II, UEFI, implementation of Python, PREFIX and EXEC_PREFIX\r
15 are set as follows:\r
16 PREFIX = /Efi/StdLib\r
17 EXEC_PREFIX = PREFIX\r
18\r
19 The following final paths are assumed:\r
20 /Efi/Tools/Python.efi The Python executable.\r
21 /Efi/StdLib/lib/python.VERSION The platform independent Python modules.\r
22 /Efi/StdLib/lib/python.VERSION/dynalib Dynamically loadable Python extension modules.\r
23\r
24 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
25 This program and the accompanying materials are licensed and made available under\r
26 the terms and conditions of the BSD License that accompanies this distribution.\r
27 The full text of the license may be found at\r
28 http://opensource.org/licenses/bsd-license.\r
29\r
30 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
31 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
32**/\r
33#include <Python.h>\r
34#include <osdefs.h>\r
b410d6e4 35#include <ctype.h>\r
41b152c5 36\r
37#ifdef __cplusplus\r
38 extern "C" {\r
39#endif\r
40\r
41/* VERSION must be at least two characters long. */\r
42#ifndef VERSION\r
43 #define VERSION "27"\r
44#endif\r
45\r
46#ifndef VPATH\r
47 #define VPATH "."\r
48#endif\r
49\r
50/* Search path entry delimiter */\r
51#ifdef DELIM\r
52 #define sDELIM ";"\r
53#endif\r
54\r
55#ifndef PREFIX\r
56 #define PREFIX "/Efi/StdLib"\r
57#endif\r
58\r
59#ifndef EXEC_PREFIX\r
60 #define EXEC_PREFIX PREFIX\r
61#endif\r
62\r
63#ifndef LIBPYTHON\r
64 #define LIBPYTHON "lib/python." VERSION\r
65#endif\r
66\r
67#ifndef PYTHONPATH\r
68//#define PYTHONPATH PREFIX LIBPYTHON sDELIM \\r
69// EXEC_PREFIX LIBPYTHON "/lib-dynload"\r
70 #define PYTHONPATH LIBPYTHON // sDELIM\r
71// LIBPYTHON "/lib-dynload"\r
72#endif\r
73\r
74#ifndef LANDMARK\r
75#define LANDMARK "os.py"\r
76#endif\r
77\r
78static char prefix[MAXPATHLEN+1];\r
79static char exec_prefix[MAXPATHLEN+1];\r
80static char progpath[MAXPATHLEN+1];\r
81static char *module_search_path = NULL;\r
82static char lib_python[] = LIBPYTHON;\r
83static char volume_name[32] = { 0 };\r
84\r
85/** Determine if "ch" is a separator character.\r
86\r
87 @param[in] ch The character to test.\r
88\r
89 @retval TRUE ch is a separator character.\r
90 @retval FALSE ch is NOT a separator character.\r
91**/\r
92static int\r
93is_sep(char ch)\r
94{\r
95#ifdef ALTSEP\r
96 return ch == SEP || ch == ALTSEP;\r
97#else\r
98 return ch == SEP;\r
99#endif\r
100}\r
101\r
102/** Reduce a path by its last element.\r
103\r
104 The last element (everything to the right of the last separator character)\r
105 in the path, dir, is removed from the path. Parameter dir is modified in place.\r
106\r
107 @param[in,out] dir Pointer to the path to modify.\r
108**/\r
109static void\r
110reduce(char *dir)\r
111{\r
112 size_t i = strlen(dir);\r
113 while (i > 0 && !is_sep(dir[i]))\r
114 --i;\r
115 dir[i] = '\0';\r
116}\r
117\r
118/** Does filename point to a file and not directory?\r
119\r
120 @param[in] filename The fully qualified path to the object to test.\r
121\r
122 @retval 0 Filename was not found, or is a directory.\r
123 @retval 1 Filename refers to a regular file.\r
124**/\r
125static int\r
126isfile(char *filename)\r
127{\r
128 struct stat buf;\r
129 if (stat(filename, &buf) != 0) {\r
41b152c5 130 return 0;\r
131 }\r
132 //if (!S_ISREG(buf.st_mode))\r
133 if (S_ISDIR(buf.st_mode)) {\r
41b152c5 134 return 0;\r
135 }\r
41b152c5 136 return 1;\r
137}\r
138\r
139/** Determine if filename refers to a Python module.\r
140\r
141 A Python module is indicated if the file exists, or if the file with\r
142 'o' or 'c' appended exists.\r
143\r
144 @param[in] filename The fully qualified path to the object to test.\r
145\r
146 @retval 0\r
147**/\r
148static int\r
149ismodule(char *filename)\r
150{\r
151 if (isfile(filename)) {\r
152 //if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: file = \"%s\"\n", __func__, __LINE__, filename);\r
153 return 1;\r
154 }\r
155\r
156 /* Check for the compiled version of prefix. */\r
157 if (strlen(filename) < MAXPATHLEN) {\r
158 strcat(filename, Py_OptimizeFlag ? "o" : "c");\r
159 if (isfile(filename)) {\r
41b152c5 160 return 1;\r
161 }\r
162 }\r
41b152c5 163 return 0;\r
164}\r
165\r
166/** Does filename point to a directory?\r
167\r
168 @param[in] filename The fully qualified path to the object to test.\r
169\r
170 @retval 0 Filename was not found, or is not a regular file.\r
171 @retval 1 Filename refers to a directory.\r
172**/\r
173static int\r
174isdir(char *filename)\r
175{\r
176 struct stat buf;\r
177\r
178 if (stat(filename, &buf) != 0)\r
179 return 0;\r
180\r
181 if (!S_ISDIR(buf.st_mode))\r
182 return 0;\r
183\r
184 return 1;\r
185}\r
186\r
187/** Determine if a path is absolute, or not.\r
188 An absolute path consists of a volume name, "VOL:", followed by a rooted path,\r
189 "/path/elements". If both of these components are present, the path is absolute.\r
190\r
191 Let P be a pointer to the path to test.\r
192 Let A be a pointer to the first ':' in P.\r
193 Let B be a pointer to the first '/' or '\\' in P.\r
194\r
195 If A and B are not NULL\r
196 If (A-P+1) == (B-P) then the path is absolute.\r
197 Otherwise, the path is NOT absolute.\r
198\r
199 @param[in] path The path to test.\r
200\r
201 @retval -1 Path is absolute but lacking volume name.\r
202 @retval 0 Path is NOT absolute.\r
203 @retval 1 Path is absolute.\r
204*/\r
205static int\r
206is_absolute(char *path)\r
207{\r
208 char *A;\r
209 char *B;\r
210\r
211 A = strchr(path, ':');\r
212 B = strpbrk(path, "/\\");\r
213\r
214 if(B != NULL) {\r
215 if(A == NULL) {\r
216 if(B == path) {\r
217 return -1;\r
218 }\r
219 }\r
220 else {\r
221 if(((A - path) + 1) == (B - path)) {\r
222 return 1;\r
223 }\r
224 }\r
225 }\r
226 return 0;\r
227}\r
228\r
229\r
230/** Add a path component, by appending stuff to buffer.\r
231 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a\r
232 NUL-terminated string with no more than MAXPATHLEN characters (not counting\r
233 the trailing NUL). It's a fatal error if it contains a string longer than\r
234 that (callers must be careful!). If these requirements are met, it's\r
235 guaranteed that buffer will still be a NUL-terminated string with no more\r
236 than MAXPATHLEN characters at exit. If stuff is too long, only as much of\r
237 stuff as fits will be appended.\r
238\r
239 @param[in,out] buffer The path to be extended.\r
240 @param[in] stuff The stuff to join onto the path.\r
241*/\r
242static void\r
243joinpath(char *buffer, char *stuff)\r
244{\r
245 size_t n, k;\r
246\r
247 k = 0;\r
248 if (is_absolute(stuff) == 1) {\r
249 n = 0;\r
250 }\r
251 else {\r
252 n = strlen(buffer);\r
253 if(n == 0) {\r
254 strncpy(buffer, volume_name, MAXPATHLEN);\r
255 n = strlen(buffer);\r
256 }\r
257 /* We must not use an else clause here because we want to test n again.\r
258 volume_name may have been empty.\r
259 */\r
260 if (n > 0 && n < MAXPATHLEN) {\r
261 if(!is_sep(buffer[n-1])) {\r
262 buffer[n++] = SEP;\r
263 }\r
264 if(is_sep(stuff[0])) ++stuff;\r
265 }\r
266 }\r
267 if (n > MAXPATHLEN)\r
268 Py_FatalError("buffer overflow in getpath.c's joinpath()");\r
269 k = strlen(stuff);\r
270 if (n + k > MAXPATHLEN)\r
271 k = MAXPATHLEN - n;\r
272 strncpy(buffer+n, stuff, k);\r
273 buffer[n+k] = '\0';\r
274}\r
275\r
276/** Is filename an executable file?\r
277\r
278 An executable file:\r
279 1) exists\r
280 2) is a file, not a directory\r
281 3) has a name ending with ".efi"\r
282 4) Only has a single '.' in the name.\r
283\r
284 If basename(filename) does not contain a '.', append ".efi" to filename\r
285 If filename ends in ".efi", it is executable, else it isn't.\r
286\r
287 This routine is used to when searching for the file named by argv[0].\r
288 As such, there is no need to search for extensions other than ".efi".\r
289\r
290 @param[in] filename The name of the file to test. It may, or may not, have an extension.\r
291\r
292 @retval 0 filename already has a path other than ".efi", or it doesn't exist, or is a directory.\r
293 @retval 1 filename refers to an executable file.\r
294**/\r
295static int\r
296isxfile(char *filename)\r
297{\r
298 struct stat buf;\r
299 char *bn;\r
300 char *newbn;\r
301 int bnlen;\r
302\r
41b152c5 303 bn = basename(filename); // Separate off the file name component\r
304 reduce(filename); // and isolate the path component\r
305 bnlen = strlen(bn);\r
306 newbn = strrchr(bn, '.'); // Does basename contain a period?\r
307 if(newbn == NULL) { // Does NOT contain a period.\r
308 newbn = &bn[bnlen];\r
309 strncpyX(newbn, ".efi", MAXPATHLEN - bnlen); // append ".efi" to basename\r
310 bnlen += 4;\r
311 }\r
312 else if(strcmp(newbn, ".efi") != 0) {\r
41b152c5 313 return 0; // File can not be executable.\r
314 }\r
315 joinpath(filename, bn); // Stitch path and file name back together\r
41b152c5 316\r
317 if (stat(filename, &buf) != 0) { // Now, verify that file exists\r
41b152c5 318 return 0;\r
319 }\r
320 if(S_ISDIR(buf.st_mode)) { // And it is not a directory.\r
41b152c5 321 return 0;\r
322 }\r
323\r
41b152c5 324 return 1;\r
325}\r
326\r
327/** Copy p into path, ensuring that the result is an absolute path.\r
328\r
329 copy_absolute requires that path be allocated at least\r
330 MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes.\r
331\r
332 @param[out] path Destination to receive the absolute path.\r
333 @param[in] p Path to be tested and possibly converted.\r
334**/\r
335static void\r
336copy_absolute(char *path, char *p)\r
337{\r
338 if (is_absolute(p) == 1)\r
339 strcpy(path, p);\r
340 else {\r
341 if (!getcwd(path, MAXPATHLEN)) {\r
342 /* unable to get the current directory */\r
343 if(volume_name[0] != 0) {\r
344 strcpy(path, volume_name);\r
345 joinpath(path, p);\r
346 }\r
347 else\r
348 strcpy(path, p);\r
349 return;\r
350 }\r
351 if (p[0] == '.' && is_sep(p[1]))\r
352 p += 2;\r
353 joinpath(path, p);\r
354 }\r
355}\r
356\r
357/** Modify path so that the result is an absolute path.\r
358 absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes.\r
359\r
360 @param[in,out] path The path to be made absolute.\r
361*/\r
362static void\r
363absolutize(char *path)\r
364{\r
365 char buffer[MAXPATHLEN + 1];\r
366\r
367 if (is_absolute(path) == 1)\r
368 return;\r
369 copy_absolute(buffer, path);\r
370 strcpy(path, buffer);\r
371}\r
372\r
373/** Extract the volume name from a path.\r
374\r
375 @param[out] Dest Pointer to location in which to store the extracted volume name.\r
376 @param[in] path Pointer to the path to extract the volume name from.\r
377**/\r
378static void\r
379set_volume(char *Dest, char *path)\r
380{\r
381 size_t VolLen;\r
382\r
41b152c5 383 if(is_absolute(path)) {\r
384 VolLen = strcspn(path, "/\\:");\r
41b152c5 385 if((VolLen != 0) && (path[VolLen] == ':')) {\r
386 (void) strncpyX(Dest, path, VolLen + 1);\r
41b152c5 387 }\r
388 }\r
41b152c5 389}\r
390\r
391\r
392/** Determine paths.\r
393\r
394 Two directories must be found, the platform independent directory\r
395 (prefix), containing the common .py and .pyc files, and the platform\r
396 dependent directory (exec_prefix), containing the shared library\r
397 modules. Note that prefix and exec_prefix are the same directory\r
398 for UEFI installations.\r
399\r
400 Separate searches are carried out for prefix and exec_prefix.\r
401 Each search tries a number of different locations until a ``landmark''\r
402 file or directory is found. If no prefix or exec_prefix is found, a\r
403 warning message is issued and the preprocessor defined PREFIX and\r
404 EXEC_PREFIX are used (even though they may not work); python carries on\r
405 as best as is possible, but some imports may fail.\r
406\r
407 Before any searches are done, the location of the executable is\r
408 determined. If argv[0] has one or more slashes in it, it is used\r
409 unchanged. Otherwise, it must have been invoked from the shell's path,\r
410 so we search %PATH% for the named executable and use that. If the\r
411 executable was not found on %PATH% (or there was no %PATH% environment\r
412 variable), the original argv[0] string is used.\r
413\r
414 Finally, argv0_path is set to the directory containing the executable\r
415 (i.e. the last component is stripped).\r
416\r
417 With argv0_path in hand, we perform a number of steps. The same steps\r
418 are performed for prefix and for exec_prefix, but with a different\r
419 landmark.\r
420\r
421 The prefix landmark will always be lib/python.VERSION/os.py and the\r
422 exec_prefix will always be lib/python.VERSION/dynaload, where VERSION\r
423 is Python's version number as defined at the beginning of this file.\r
424\r
425 First. See if the %PYTHONHOME% environment variable points to the\r
426 installed location of the Python libraries. If %PYTHONHOME% is set, then\r
427 it points to prefix and exec_prefix. %PYTHONHOME% can be a single\r
428 directory, which is used for both, or the prefix and exec_prefix\r
429 directories separated by the DELIM character.\r
430\r
431 Next. Search the directories pointed to by the preprocessor variables\r
432 PREFIX and EXEC_PREFIX. These paths are prefixed with the volume name\r
433 extracted from argv0_path. The volume names correspond to the UEFI\r
434 shell "map" names.\r
435\r
436 That's it!\r
437\r
438 Well, almost. Once we have determined prefix and exec_prefix, the\r
439 preprocessor variable PYTHONPATH is used to construct a path. Each\r
440 relative path on PYTHONPATH is prefixed with prefix. Then the directory\r
441 containing the shared library modules is appended. The environment\r
442 variable $PYTHONPATH is inserted in front of it all. Finally, the\r
443 prefix and exec_prefix globals are tweaked so they reflect the values\r
444 expected by other code, by stripping the "lib/python$VERSION/..." stuff\r
445 off. This seems to make more sense given that currently the only\r
446 known use of sys.prefix and sys.exec_prefix is for the ILU installation\r
447 process to find the installed Python tree.\r
448\r
449 The final, fully resolved, paths should look something like:\r
450 fs0:/Efi/Tools/python.efi\r
451 fs0:/Efi/StdLib/lib/python27\r
452 fs0:/Efi/StdLib/lib/python27/dynaload\r
453\r
454**/\r
455static void\r
456calculate_path(void)\r
457{\r
458 extern char *Py_GetProgramName(void);\r
459\r
460 static char delimiter[2] = {DELIM, '\0'};\r
461 static char separator[2] = {SEP, '\0'};\r
462 char *pythonpath = PYTHONPATH;\r
463 char *rtpypath = Py_GETENV("PYTHONPATH");\r
464 //char *home = Py_GetPythonHome();\r
465 char *path = getenv("PATH");\r
466 char *prog = Py_GetProgramName();\r
467 char argv0_path[MAXPATHLEN+1];\r
468 char zip_path[MAXPATHLEN+1];\r
41b152c5 469 char *buf;\r
470 size_t bufsz;\r
471 size_t prefixsz;\r
472 char *defpath;\r
41b152c5 473\r
474\r
475/* ###########################################################################\r
476 Determine path to the Python.efi binary.\r
477 Produces progpath, argv0_path, and volume_name.\r
478########################################################################### */\r
479\r
480 /* If there is no slash in the argv0 path, then we have to\r
481 * assume python is on the user's $PATH, since there's no\r
482 * other way to find a directory to start the search from. If\r
483 * $PATH isn't exported, you lose.\r
484 */\r
485 if (strchr(prog, SEP))\r
486 strncpy(progpath, prog, MAXPATHLEN);\r
487 else if (path) {\r
488 while (1) {\r
489 char *delim = strchr(path, DELIM);\r
490\r
491 if (delim) {\r
492 size_t len = delim - path;\r
493 if (len > MAXPATHLEN)\r
494 len = MAXPATHLEN;\r
495 strncpy(progpath, path, len);\r
496 *(progpath + len) = '\0';\r
497 }\r
498 else\r
499 strncpy(progpath, path, MAXPATHLEN);\r
500\r
501 joinpath(progpath, prog);\r
41b152c5 502 if (isxfile(progpath))\r
503 break;\r
504\r
505 if (!delim) {\r
506 progpath[0] = '\0';\r
507 break;\r
508 }\r
509 path = delim + 1;\r
510 }\r
511 }\r
512 else\r
513 progpath[0] = '\0';\r
514 if ( (!is_absolute(progpath)) && (progpath[0] != '\0') )\r
515 absolutize(progpath);\r
516 strncpy(argv0_path, progpath, MAXPATHLEN);\r
517 argv0_path[MAXPATHLEN] = '\0';\r
518 set_volume(volume_name, argv0_path);\r
519\r
41b152c5 520 reduce(argv0_path);\r
41b152c5 521 /* At this point, argv0_path is guaranteed to be less than\r
522 MAXPATHLEN bytes long.\r
523 */\r
524\r
525/* ###########################################################################\r
526 Build the FULL prefix string, including volume name.\r
527 This is the full path to the platform independent libraries.\r
528########################################################################### */\r
529\r
41b152c5 530 strncpy(prefix, volume_name, MAXPATHLEN);\r
531 joinpath(prefix, PREFIX);\r
532 joinpath(prefix, lib_python);\r
41b152c5 533\r
534/* ###########################################################################\r
535 Build the FULL path to the zipped-up Python library.\r
536########################################################################### */\r
537\r
538 strncpy(zip_path, prefix, MAXPATHLEN);\r
539 zip_path[MAXPATHLEN] = '\0';\r
b410d6e4 540 reduce(zip_path);\r
41b152c5 541 joinpath(zip_path, "python00.zip");\r
542 bufsz = strlen(zip_path); /* Replace "00" with version */\r
543 zip_path[bufsz - 6] = VERSION[0];\r
544 zip_path[bufsz - 5] = VERSION[1];\r
41b152c5 545\r
546/* ###########################################################################\r
547 Build the FULL path to dynamically loadable libraries.\r
548########################################################################### */\r
549\r
41b152c5 550 strncpy(exec_prefix, volume_name, MAXPATHLEN);\r
551 joinpath(exec_prefix, EXEC_PREFIX);\r
552 joinpath(exec_prefix, lib_python);\r
b410d6e4 553 joinpath(exec_prefix, "lib-dynload");\r
41b152c5 554\r
555/* ###########################################################################\r
556 Build the module search path.\r
557########################################################################### */\r
558\r
559 /* Reduce prefix and exec_prefix to their essence,\r
560 * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.\r
561 * If we're loading relative to the build directory,\r
562 * return the compiled-in defaults instead.\r
563 */\r
41b152c5 564 reduce(prefix);\r
565 reduce(prefix);\r
566 /* The prefix is the root directory, but reduce() chopped\r
567 * off the "/". */\r
568 if (!prefix[0]) {\r
569 strcpy(prefix, volume_name);\r
570 }\r
571 bufsz = strlen(prefix);\r
572 if(prefix[bufsz-1] == ':') {\r
573 prefix[bufsz] = SEP;\r
574 prefix[bufsz+1] = 0;\r
575 }\r
41b152c5 576\r
577 /* Calculate size of return buffer.\r
578 */\r
579 defpath = pythonpath;\r
580 bufsz = 0;\r
581\r
582 if (rtpypath)\r
583 bufsz += strlen(rtpypath) + 1;\r
584\r
585 prefixsz = strlen(prefix) + 1;\r
586\r
587 while (1) {\r
588 char *delim = strchr(defpath, DELIM);\r
589\r
590 if (is_absolute(defpath) == 0)\r
591 /* Paths are relative to prefix */\r
592 bufsz += prefixsz;\r
593\r
594 if (delim)\r
595 bufsz += delim - defpath + 1;\r
596 else {\r
597 bufsz += strlen(defpath) + 1;\r
598 break;\r
599 }\r
600 defpath = delim + 1;\r
601 }\r
41b152c5 602\r
603 bufsz += strlen(zip_path) + 1;\r
604 bufsz += strlen(exec_prefix) + 1;\r
605\r
606 /* This is the only malloc call in this file */\r
607 buf = (char *)PyMem_Malloc(bufsz);\r
608\r
609 if (buf == NULL) {\r
610 /* We can't exit, so print a warning and limp along */\r
611 fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");\r
612 fprintf(stderr, "Using default static PYTHONPATH.\n");\r
613 module_search_path = PYTHONPATH;\r
614 }\r
615 else {\r
41b152c5 616 /* Run-time value of $PYTHONPATH goes first */\r
617 if (rtpypath) {\r
618 strcpy(buf, rtpypath);\r
619 strcat(buf, delimiter);\r
620 }\r
621 else\r
622 buf[0] = '\0';\r
41b152c5 623\r
624 /* Next is the default zip path */\r
625 strcat(buf, zip_path);\r
626 strcat(buf, delimiter);\r
41b152c5 627\r
628 /* Next goes merge of compile-time $PYTHONPATH with\r
629 * dynamically located prefix.\r
630 */\r
631 defpath = pythonpath;\r
632 while (1) {\r
633 char *delim = strchr(defpath, DELIM);\r
634\r
635 if (is_absolute(defpath) != 1) {\r
636 strcat(buf, prefix);\r
637 strcat(buf, separator);\r
638 }\r
639\r
640 if (delim) {\r
641 size_t len = delim - defpath + 1;\r
642 size_t end = strlen(buf) + len;\r
643 strncat(buf, defpath, len);\r
644 *(buf + end) = '\0';\r
645 }\r
646 else {\r
647 strcat(buf, defpath);\r
648 break;\r
649 }\r
650 defpath = delim + 1;\r
651 }\r
652 strcat(buf, delimiter);\r
41b152c5 653\r
654 /* Finally, on goes the directory for dynamic-load modules */\r
655 strcat(buf, exec_prefix);\r
656\r
657 /* And publish the results */\r
658 module_search_path = buf;\r
41b152c5 659 }\r
41b152c5 660 /* At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib.\r
661 We want to get back to the root value, so we have to remove the final three\r
662 segments to get VOL:/Efi/StdLib. Because we don't know what VOL is, and\r
663 EXEC_PREFIX is also indeterminate, we just remove the three final segments.\r
664 */\r
665 reduce(exec_prefix);\r
666 reduce(exec_prefix);\r
667 reduce(exec_prefix);\r
668 if (!exec_prefix[0]) {\r
669 strcpy(exec_prefix, volume_name);\r
670 }\r
671 bufsz = strlen(exec_prefix);\r
672 if(exec_prefix[bufsz-1] == ':') {\r
673 exec_prefix[bufsz] = SEP;\r
674 exec_prefix[bufsz+1] = 0;\r
675 }\r
41b152c5 676 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path);\r
677 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix = \"%s\"\n", __func__, __LINE__, prefix);\r
678 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix = \"%s\"\n", __func__, __LINE__, exec_prefix);\r
679 if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath = \"%s\"\n", __func__, __LINE__, progpath);\r
680}\r
681\r
682\r
683/* External interface */\r
684\r
685char *\r
686Py_GetPath(void)\r
687{\r
688 if (!module_search_path)\r
689 calculate_path();\r
690 return module_search_path;\r
691}\r
692\r
693char *\r
694Py_GetPrefix(void)\r
695{\r
696 if (!module_search_path)\r
697 calculate_path();\r
698 return prefix;\r
699}\r
700\r
701char *\r
702Py_GetExecPrefix(void)\r
703{\r
704 if (!module_search_path)\r
705 calculate_path();\r
706 return exec_prefix;\r
707}\r
708\r
709char *\r
710Py_GetProgramFullPath(void)\r
711{\r
712 if (!module_search_path)\r
713 calculate_path();\r
714 return progpath;\r
715}\r
716\r
717\r
718#ifdef __cplusplus\r
719}\r
720#endif\r
721\r