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