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