bpo-34783: Fix Py_Main() (GH-9526)
Fix a crash with musl libc (on Alpine Linux) when the script filename specified on the command line doesn't exist. pymain_open_filename() now gets the current core configuration from the interpreter state. Modify the code to make it closer to the master branch: * Rename _Py_CommandLineDetails to _PyCmdline * Remove _PyMain.config: replaced with a local variable 'local_config' in pymain_init() * Reorganize pymain_main(): move code using the "local config" into pymain_init() * As soon as possible, switch from the local config to the core configuration attached to the interpreter.
This commit is contained in:
parent
aeadf59e45
commit
ddc163df25
|
@ -0,0 +1,2 @@
|
||||||
|
Fix a crash with musl libc (on Alpine Linux) when the script filename
|
||||||
|
specified on the command line doesn't exist.
|
163
Modules/main.c
163
Modules/main.c
|
@ -459,7 +459,7 @@ typedef struct {
|
||||||
int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
|
int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
|
||||||
PYTHONLEGACYWINDOWSSTDIO */
|
PYTHONLEGACYWINDOWSSTDIO */
|
||||||
#endif
|
#endif
|
||||||
} _Py_CommandLineDetails;
|
} _PyCmdline;
|
||||||
|
|
||||||
/* Structure used by Py_Main() to pass data to subfunctions */
|
/* Structure used by Py_Main() to pass data to subfunctions */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -481,14 +481,10 @@ typedef struct {
|
||||||
wchar_t *command; /* -c argument */
|
wchar_t *command; /* -c argument */
|
||||||
wchar_t *module; /* -m argument */
|
wchar_t *module; /* -m argument */
|
||||||
|
|
||||||
_PyCoreConfig config;
|
|
||||||
|
|
||||||
PyObject *main_importer_path;
|
PyObject *main_importer_path;
|
||||||
} _PyMain;
|
} _PyMain;
|
||||||
|
|
||||||
#define _PyMain_INIT \
|
#define _PyMain_INIT {.err = _Py_INIT_OK()}
|
||||||
{.config = _PyCoreConfig_INIT, \
|
|
||||||
.err = _Py_INIT_OK()}
|
|
||||||
/* Note: _PyMain_INIT sets other fields to 0/NULL */
|
/* Note: _PyMain_INIT sets other fields to 0/NULL */
|
||||||
|
|
||||||
|
|
||||||
|
@ -522,7 +518,8 @@ clear_wstrlist(int len, wchar_t **list)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_init_cmdline_argv(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
assert(cmdline->argv == NULL);
|
assert(cmdline->argv == NULL);
|
||||||
|
|
||||||
|
@ -561,8 +558,8 @@ pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
else {
|
else {
|
||||||
program = L"";
|
program = L"";
|
||||||
}
|
}
|
||||||
pymain->config.program = pymain_wstrdup(pymain, program);
|
config->program = pymain_wstrdup(pymain, program);
|
||||||
if (pymain->config.program == NULL) {
|
if (config->program == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +568,7 @@ pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_clear_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_clear_cmdline(_PyMain *pymain, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
PyMemAllocatorEx old_alloc;
|
PyMemAllocatorEx old_alloc;
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
@ -609,14 +606,14 @@ pymain_clear_pymain(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pymain_clear_config(_PyMain *pymain)
|
pymain_clear_config(_PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
/* Clear core config with the memory allocator
|
/* Clear core config with the memory allocator
|
||||||
used by pymain_read_conf() */
|
used by pymain_read_conf() */
|
||||||
PyMemAllocatorEx old_alloc;
|
PyMemAllocatorEx old_alloc;
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
_PyCoreConfig_Clear(&pymain->config);
|
_PyCoreConfig_Clear(config);
|
||||||
|
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
}
|
}
|
||||||
|
@ -653,8 +650,6 @@ pymain_free_raw(_PyMain *pymain)
|
||||||
Py_Initialize()-Py_Finalize() can be called multiple times. */
|
Py_Initialize()-Py_Finalize() can be called multiple times. */
|
||||||
_PyPathConfig_Clear(&_Py_path_config);
|
_PyPathConfig_Clear(&_Py_path_config);
|
||||||
|
|
||||||
pymain_clear_config(pymain);
|
|
||||||
|
|
||||||
/* Force the allocator used by pymain_read_conf() */
|
/* Force the allocator used by pymain_read_conf() */
|
||||||
PyMemAllocatorEx old_alloc;
|
PyMemAllocatorEx old_alloc;
|
||||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
@ -740,10 +735,9 @@ pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t
|
||||||
Return 1 if parsing failed.
|
Return 1 if parsing failed.
|
||||||
Set pymain->err and return -1 on other errors. */
|
Set pymain->err and return -1 on other errors. */
|
||||||
static int
|
static int
|
||||||
pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_parse_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
|
|
||||||
_PyOS_ResetGetOpt();
|
_PyOS_ResetGetOpt();
|
||||||
do {
|
do {
|
||||||
int longindex = -1;
|
int longindex = -1;
|
||||||
|
@ -985,7 +979,7 @@ config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)
|
||||||
|
|
||||||
|
|
||||||
static _PyInitError
|
static _PyInitError
|
||||||
config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
|
config_init_warnoptions(_PyCoreConfig *config, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
|
@ -1056,7 +1050,7 @@ config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
|
||||||
Return 0 on success.
|
Return 0 on success.
|
||||||
Set pymain->err and return -1 on error. */
|
Set pymain->err and return -1 on error. */
|
||||||
static _PyInitError
|
static _PyInitError
|
||||||
cmdline_init_env_warnoptions(_Py_CommandLineDetails *cmdline)
|
cmdline_init_env_warnoptions(_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
if (Py_IgnoreEnvironmentFlag) {
|
if (Py_IgnoreEnvironmentFlag) {
|
||||||
return _Py_INIT_OK();
|
return _Py_INIT_OK();
|
||||||
|
@ -1252,7 +1246,8 @@ copy_wstrlist(int len, wchar_t **list)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init_core_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_init_core_argv(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
/* Copy argv to be able to modify it (to force -c/-m) */
|
/* Copy argv to be able to modify it (to force -c/-m) */
|
||||||
int argc = pymain->argc - _PyOS_optind;
|
int argc = pymain->argc - _PyOS_optind;
|
||||||
|
@ -1295,8 +1290,8 @@ pymain_init_core_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
argv[0] = arg0;
|
argv[0] = arg0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain->config.argc = argc;
|
config->argc = argc;
|
||||||
pymain->config.argv = argv;
|
config->argv = argv;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,7 +1319,7 @@ wstrlist_as_pylist(int len, wchar_t **list)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_compute_path0(_PyMain *pymain, PyObject **path0)
|
pymain_compute_path0(_PyMain *pymain, _PyCoreConfig *config, PyObject **path0)
|
||||||
{
|
{
|
||||||
if (pymain->main_importer_path != NULL) {
|
if (pymain->main_importer_path != NULL) {
|
||||||
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */
|
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */
|
||||||
|
@ -1337,8 +1332,7 @@ pymain_compute_path0(_PyMain *pymain, PyObject **path0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*path0 = _PyPathConfig_ComputeArgv0(pymain->config.argc,
|
*path0 = _PyPathConfig_ComputeArgv0(config->argc, config->argv);
|
||||||
pymain->config.argv);
|
|
||||||
if (*path0 == NULL) {
|
if (*path0 == NULL) {
|
||||||
pymain->err = _Py_INIT_NO_MEMORY();
|
pymain->err = _Py_INIT_NO_MEMORY();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1384,7 +1378,7 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
|
||||||
|
|
||||||
/* Get Py_xxx global configuration variables */
|
/* Get Py_xxx global configuration variables */
|
||||||
static void
|
static void
|
||||||
cmdline_get_global_config(_Py_CommandLineDetails *cmdline)
|
cmdline_get_global_config(_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
cmdline->bytes_warning = Py_BytesWarningFlag;
|
cmdline->bytes_warning = Py_BytesWarningFlag;
|
||||||
cmdline->debug = Py_DebugFlag;
|
cmdline->debug = Py_DebugFlag;
|
||||||
|
@ -1420,7 +1414,7 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
|
||||||
|
|
||||||
/* Set Py_xxx global configuration variables */
|
/* Set Py_xxx global configuration variables */
|
||||||
static void
|
static void
|
||||||
cmdline_set_global_config(_Py_CommandLineDetails *cmdline)
|
cmdline_set_global_config(_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
Py_BytesWarningFlag = cmdline->bytes_warning;
|
Py_BytesWarningFlag = cmdline->bytes_warning;
|
||||||
Py_DebugFlag = cmdline->debug;
|
Py_DebugFlag = cmdline->debug;
|
||||||
|
@ -1468,6 +1462,7 @@ pymain_import_readline(_PyMain *pymain)
|
||||||
static FILE*
|
static FILE*
|
||||||
pymain_open_filename(_PyMain *pymain)
|
pymain_open_filename(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
|
const _PyCoreConfig *config = &_PyGILState_GetInterpreterStateUnsafe()->core_config;
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
|
|
||||||
fp = _Py_wfopen(pymain->filename, L"r");
|
fp = _Py_wfopen(pymain->filename, L"r");
|
||||||
|
@ -1481,7 +1476,7 @@ pymain_open_filename(_PyMain *pymain)
|
||||||
else
|
else
|
||||||
cfilename = "<unprintable file name>";
|
cfilename = "<unprintable file name>";
|
||||||
fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
|
fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
|
||||||
pymain->config.program, cfilename, err, strerror(err));
|
config->program, cfilename, err, strerror(err));
|
||||||
PyMem_RawFree(cfilename_buffer);
|
PyMem_RawFree(cfilename_buffer);
|
||||||
pymain->status = 2;
|
pymain->status = 2;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1504,7 +1499,7 @@ pymain_open_filename(_PyMain *pymain)
|
||||||
S_ISDIR(sb.st_mode)) {
|
S_ISDIR(sb.st_mode)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%ls: '%ls' is a directory, cannot continue\n",
|
"%ls: '%ls' is a directory, cannot continue\n",
|
||||||
pymain->config.program, pymain->filename);
|
config->program, pymain->filename);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
pymain->status = 1;
|
pymain->status = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1571,14 +1566,15 @@ pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
|
||||||
Return 0 on success.
|
Return 0 on success.
|
||||||
Set pymain->err and return -1 on failure. */
|
Set pymain->err and return -1 on failure. */
|
||||||
static int
|
static int
|
||||||
pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_parse_cmdline(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
int res = pymain_parse_cmdline_impl(pymain, cmdline);
|
int res = pymain_parse_cmdline_impl(pymain, config, cmdline);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
pymain_usage(1, pymain->config.program);
|
pymain_usage(1, config->program);
|
||||||
pymain->status = 2;
|
pymain->status = 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1716,7 +1712,7 @@ get_env_flag(int *flag, const char *name)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmdline_get_env_flags(_Py_CommandLineDetails *cmdline)
|
cmdline_get_env_flags(_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
get_env_flag(&cmdline->debug, "PYTHONDEBUG");
|
get_env_flag(&cmdline->debug, "PYTHONDEBUG");
|
||||||
get_env_flag(&cmdline->verbosity, "PYTHONVERBOSE");
|
get_env_flag(&cmdline->verbosity, "PYTHONVERBOSE");
|
||||||
|
@ -1738,7 +1734,7 @@ cmdline_get_env_flags(_Py_CommandLineDetails *cmdline)
|
||||||
void
|
void
|
||||||
_Py_Initialize_ReadEnvVarsNoAlloc(void)
|
_Py_Initialize_ReadEnvVarsNoAlloc(void)
|
||||||
{
|
{
|
||||||
_Py_CommandLineDetails cmdline;
|
_PyCmdline cmdline;
|
||||||
memset(&cmdline, 0, sizeof(cmdline));
|
memset(&cmdline, 0, sizeof(cmdline));
|
||||||
|
|
||||||
cmdline_get_global_config(&cmdline);
|
cmdline_get_global_config(&cmdline);
|
||||||
|
@ -1926,17 +1922,17 @@ config_read_complex_options(_PyCoreConfig *config)
|
||||||
Return 1 if Python is done and must exit.
|
Return 1 if Python is done and must exit.
|
||||||
Set pymain->err and return -1 on error. */
|
Set pymain->err and return -1 on error. */
|
||||||
static int
|
static int
|
||||||
pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_read_conf_impl(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
_PyInitError err;
|
_PyInitError err;
|
||||||
|
|
||||||
int res = pymain_parse_cmdline(pymain, cmdline);
|
int res = pymain_parse_cmdline(pymain, config, cmdline);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */
|
/* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
Py_IgnoreEnvironmentFlag = config->ignore_environment || cmdline->isolated;
|
Py_IgnoreEnvironmentFlag = config->ignore_environment || cmdline->isolated;
|
||||||
|
|
||||||
/* Get environment variables */
|
/* Get environment variables */
|
||||||
|
@ -1956,7 +1952,7 @@ pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pymain_init_core_argv(pymain, cmdline) < 0) {
|
if (pymain_init_core_argv(pymain, config, cmdline) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1985,10 +1981,9 @@ pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
/* Read the configuration, but initialize also the LC_CTYPE locale:
|
/* Read the configuration, but initialize also the LC_CTYPE locale:
|
||||||
enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
|
enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
|
||||||
static int
|
static int
|
||||||
pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
int init_utf8_mode = Py_UTF8Mode;
|
int init_utf8_mode = Py_UTF8Mode;
|
||||||
_PyCoreConfig *config = &pymain->config;
|
|
||||||
_PyCoreConfig save_config = _PyCoreConfig_INIT;
|
_PyCoreConfig save_config = _PyCoreConfig_INIT;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
|
@ -2026,11 +2021,11 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
functions depend on Py_UTF8Mode. */
|
functions depend on Py_UTF8Mode. */
|
||||||
Py_UTF8Mode = config->utf8_mode;
|
Py_UTF8Mode = config->utf8_mode;
|
||||||
|
|
||||||
if (pymain_init_cmdline_argv(pymain, cmdline) < 0) {
|
if (pymain_init_cmdline_argv(pymain, config, cmdline) < 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
int conf_res = pymain_read_conf_impl(pymain, cmdline);
|
int conf_res = pymain_read_conf_impl(pymain, config, cmdline);
|
||||||
if (conf_res != 0) {
|
if (conf_res != 0) {
|
||||||
res = conf_res;
|
res = conf_res;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -2587,7 +2582,7 @@ pymain_init_python_main(_PyMain *pymain, PyInterpreterState *interp)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_init_sys_path(_PyMain *pymain)
|
pymain_init_sys_path(_PyMain *pymain, _PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
if (pymain->filename != NULL) {
|
if (pymain->filename != NULL) {
|
||||||
/* If filename is a package (ex: directory or ZIP file) which contains
|
/* If filename is a package (ex: directory or ZIP file) which contains
|
||||||
|
@ -2598,12 +2593,10 @@ pymain_init_sys_path(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *path0;
|
PyObject *path0;
|
||||||
if (pymain_compute_path0(pymain, &path0) < 0) {
|
if (pymain_compute_path0(pymain, config, &path0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain_clear_config(pymain);
|
|
||||||
|
|
||||||
if (path0 != NULL) {
|
if (path0 != NULL) {
|
||||||
if (pymain_update_sys_path(pymain, path0) < 0) {
|
if (pymain_update_sys_path(pymain, path0) < 0) {
|
||||||
Py_DECREF(path0);
|
Py_DECREF(path0);
|
||||||
|
@ -2637,32 +2630,16 @@ pymain_run_python(_PyMain *pymain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
pymain_init(_PyMain *pymain)
|
|
||||||
{
|
|
||||||
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
|
||||||
* and until C vendors implement C99's ways to control FP exceptions,
|
|
||||||
* Python requires non-stop mode. Alas, some platforms enable FP
|
|
||||||
* exceptions by default. Here we disable them.
|
|
||||||
*/
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
fedisableexcept(FE_OVERFLOW);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pymain->config._disable_importlib = 0;
|
|
||||||
pymain->config.install_signal_handlers = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
pymain_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
|
||||||
|
_PyCmdline *cmdline)
|
||||||
{
|
{
|
||||||
pymain->err = _PyRuntime_Initialize();
|
pymain->err = _PyRuntime_Initialize();
|
||||||
if (_Py_INIT_FAILED(pymain->err)) {
|
if (_Py_INIT_FAILED(pymain->err)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = pymain_read_conf(pymain, cmdline);
|
int res = pymain_read_conf(pymain, config, cmdline);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2672,7 +2649,7 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdline->print_help) {
|
if (cmdline->print_help) {
|
||||||
pymain_usage(0, pymain->config.program);
|
pymain_usage(0, config->program);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2690,7 +2667,7 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
}
|
}
|
||||||
orig_argc = pymain->argc;
|
orig_argc = pymain->argc;
|
||||||
|
|
||||||
_PyInitError err = config_init_warnoptions(&pymain->config, cmdline);
|
_PyInitError err = config_init_warnoptions(config, cmdline);
|
||||||
if (_Py_INIT_FAILED(err)) {
|
if (_Py_INIT_FAILED(err)) {
|
||||||
pymain->err = err;
|
pymain->err = err;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2708,10 +2685,10 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
|
||||||
* Environment variables
|
* Environment variables
|
||||||
* Py_xxx global configuration variables
|
* Py_xxx global configuration variables
|
||||||
|
|
||||||
_Py_CommandLineDetails is a temporary structure used to prioritize these
|
_PyCmdline is a temporary structure used to prioritize these
|
||||||
variables. */
|
variables. */
|
||||||
static int
|
static int
|
||||||
pymain_cmdline(_PyMain *pymain)
|
pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
|
||||||
{
|
{
|
||||||
/* Force default allocator, since pymain_free() and pymain_clear_config()
|
/* Force default allocator, since pymain_free() and pymain_clear_config()
|
||||||
must use the same allocator than this function. */
|
must use the same allocator than this function. */
|
||||||
|
@ -2722,16 +2699,15 @@ pymain_cmdline(_PyMain *pymain)
|
||||||
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &default_alloc);
|
PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &default_alloc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_Py_CommandLineDetails cmdline;
|
_PyCmdline cmdline;
|
||||||
memset(&cmdline, 0, sizeof(cmdline));
|
memset(&cmdline, 0, sizeof(cmdline));
|
||||||
|
|
||||||
cmdline_get_global_config(&cmdline);
|
cmdline_get_global_config(&cmdline);
|
||||||
_PyCoreConfig_GetGlobalConfig(&pymain->config);
|
|
||||||
|
|
||||||
int res = pymain_cmdline_impl(pymain, &cmdline);
|
int res = pymain_cmdline_impl(pymain, config, &cmdline);
|
||||||
|
|
||||||
cmdline_set_global_config(&cmdline);
|
cmdline_set_global_config(&cmdline);
|
||||||
_PyCoreConfig_SetGlobalConfig(&pymain->config);
|
_PyCoreConfig_SetGlobalConfig(config);
|
||||||
if (Py_IsolatedFlag) {
|
if (Py_IsolatedFlag) {
|
||||||
Py_IgnoreEnvironmentFlag = 1;
|
Py_IgnoreEnvironmentFlag = 1;
|
||||||
Py_NoUserSiteDirectory = 1;
|
Py_NoUserSiteDirectory = 1;
|
||||||
|
@ -2751,33 +2727,62 @@ pymain_cmdline(_PyMain *pymain)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pymain_main(_PyMain *pymain)
|
pymain_init(_PyMain *pymain)
|
||||||
{
|
{
|
||||||
pymain_init(pymain);
|
_PyCoreConfig local_config = _PyCoreConfig_INIT;
|
||||||
|
_PyCoreConfig *config = &local_config;
|
||||||
|
|
||||||
int res = pymain_cmdline(pymain);
|
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
||||||
|
* and until C vendors implement C99's ways to control FP exceptions,
|
||||||
|
* Python requires non-stop mode. Alas, some platforms enable FP
|
||||||
|
* exceptions by default. Here we disable them.
|
||||||
|
*/
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
fedisableexcept(FE_OVERFLOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
config->_disable_importlib = 0;
|
||||||
|
config->install_signal_handlers = 1;
|
||||||
|
_PyCoreConfig_GetGlobalConfig(config);
|
||||||
|
|
||||||
|
int res = pymain_cmdline(pymain, config);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
if (res == 1) {
|
if (res == 1) {
|
||||||
goto done;
|
pymain_clear_config(&local_config);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pymain_init_stdio(pymain);
|
pymain_init_stdio(pymain);
|
||||||
|
|
||||||
PyInterpreterState *interp;
|
PyInterpreterState *interp;
|
||||||
pymain->err = _Py_InitializeCore(&interp, &pymain->config);
|
pymain->err = _Py_InitializeCore(&interp, config);
|
||||||
if (_Py_INIT_FAILED(pymain->err)) {
|
if (_Py_INIT_FAILED(pymain->err)) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pymain_clear_config(&local_config);
|
||||||
|
config = &interp->core_config;
|
||||||
|
|
||||||
if (pymain_init_python_main(pymain, interp) < 0) {
|
if (pymain_init_python_main(pymain, interp) < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pymain_init_sys_path(pymain) < 0) {
|
if (pymain_init_sys_path(pymain, config) < 0) {
|
||||||
_Py_FatalInitError(pymain->err);
|
_Py_FatalInitError(pymain->err);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
pymain_main(_PyMain *pymain)
|
||||||
|
{
|
||||||
|
int res = pymain_init(pymain);
|
||||||
|
if (res == 1) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
pymain_run_python(pymain);
|
pymain_run_python(pymain);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue