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