1
2 /* Frozen modules bootstrap
3 *
4 * Limited and restricted Python interpreter to run
5 * "Tools/build/deepfreeze.py" on systems with no or older Python
6 * interpreter.
7 */
8
9 #include "Python.h"
10 #include "pycore_import.h"
11
12 /* Includes for frozen modules: */
13 #include "Python/frozen_modules/importlib._bootstrap.h"
14 #include "Python/frozen_modules/importlib._bootstrap_external.h"
15 #include "Python/frozen_modules/zipimport.h"
16 /* End includes */
17
18 uint32_t _Py_next_func_version = 1;
19
20 /* Empty initializer for deepfrozen modules */
21 int _Py_Deepfreeze_Init(void)
22 {
23 return 0;
24 }
25 /* Empty finalizer for deepfrozen modules */
26 void
27 _Py_Deepfreeze_Fini(void)
28 {
29 }
30
31 /* Note that a negative size indicates a package. */
32
33 static const struct _frozen bootstrap_modules[] = {
34 {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap)},
35 {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external)},
36 {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport)},
37 {0, 0, 0} /* bootstrap sentinel */
38 };
39 static const struct _frozen stdlib_modules[] = {
40 {0, 0, 0} /* stdlib sentinel */
41 };
42 static const struct _frozen test_modules[] = {
43 {0, 0, 0} /* test sentinel */
44 };
45 const struct _frozen *_PyImport_FrozenBootstrap = bootstrap_modules;
46 const struct _frozen *_PyImport_FrozenStdlib = stdlib_modules;
47 const struct _frozen *_PyImport_FrozenTest = test_modules;
48
49 static const struct _module_alias aliases[] = {
50 {"_frozen_importlib", "importlib._bootstrap"},
51 {"_frozen_importlib_external", "importlib._bootstrap_external"},
52 {0, 0} /* aliases sentinel */
53 };
54 const struct _module_alias *_PyImport_FrozenAliases = aliases;
55
56 /* Embedding apps may change this pointer to point to their favorite
57 collection of frozen modules: */
58
59 const struct _frozen *PyImport_FrozenModules = NULL;
60
61 int
62 #ifdef MS_WINDOWS
63 wmain(int argc, wchar_t **argv)
64 #else
65 main(int argc, char **argv)
66 #endif
67 {
68 PyStatus status;
69
70 PyConfig config;
71 PyConfig_InitIsolatedConfig(&config);
72 // don't warn, pybuilddir.txt does not exist yet
73 config.pathconfig_warnings = 0;
74 // parse arguments
75 config.parse_argv = 1;
76 // add current script dir to sys.path
77 config.isolated = 0;
78 config.safe_path = 0;
79
80 #ifdef MS_WINDOWS
81 status = PyConfig_SetArgv(&config, argc, argv);
82 #else
83 status = PyConfig_SetBytesArgv(&config, argc, argv);
84 #endif
85 if (PyStatus_Exception(status)) {
86 goto error;
87 }
88
89 status = PyConfig_Read(&config);
90 if (config.run_filename == NULL) {
91 status = PyStatus_Error("Run filename expected");
92 goto error;
93 }
94
95 #define CLEAR(ATTR) \
96 do { \
97 PyMem_RawFree(ATTR); \
98 ATTR = NULL; \
99 } while (0)
100
101 // isolate from system Python
102 CLEAR(config.base_prefix);
103 CLEAR(config.prefix);
104 CLEAR(config.base_exec_prefix);
105 CLEAR(config.exec_prefix);
106
107 status = Py_InitializeFromConfig(&config);
108 if (PyStatus_Exception(status)) {
109 goto error;
110 }
111 PyConfig_Clear(&config);
112
113 return Py_RunMain();
114
115 error:
116 PyConfig_Clear(&config);
117 if (PyStatus_IsExit(status)) {
118 return status.exitcode;
119 }
120 Py_ExitStatusException(status);
121 }
122