Home | History | Annotate | Download | only in Modules
      1 /* Python interpreter main program */
      2 
      3 #include "Python.h"
      4 #include "osdefs.h"
      5 #include "internal/import.h"
      6 #include "internal/pygetopt.h"
      7 #include "internal/pystate.h"
      8 
      9 #include <locale.h>
     10 
     11 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
     12 #  include <windows.h>
     13 #  ifdef HAVE_IO_H
     14 #    include <io.h>
     15 #  endif
     16 #  ifdef HAVE_FCNTL_H
     17 #    include <fcntl.h>
     18 #  endif
     19 #endif
     20 
     21 #ifdef _MSC_VER
     22 #  include <crtdbg.h>
     23 #endif
     24 
     25 #ifdef __FreeBSD__
     26 #  include <fenv.h>
     27 #endif
     28 
     29 #if defined(MS_WINDOWS)
     30 #  define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
     31 #else
     32 #  define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
     33 #endif
     34 
     35 #define COPYRIGHT \
     36     "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
     37     "for more information."
     38 
     39 #ifdef __cplusplus
     40 extern "C" {
     41 #endif
     42 
     43 #define DECODE_LOCALE_ERR(NAME, LEN) \
     44     (((LEN) == -2) \
     45      ? _Py_INIT_USER_ERR("cannot decode " NAME) \
     46      : _Py_INIT_NO_MEMORY())
     47 
     48 
     49 #define SET_DECODE_ERROR(NAME, LEN) \
     50     do { \
     51         if ((LEN) == (size_t)-2) { \
     52             pymain->err = _Py_INIT_USER_ERR("cannot decode " NAME); \
     53         } \
     54         else { \
     55             pymain->err = _Py_INIT_NO_MEMORY(); \
     56         } \
     57     } while (0)
     58 
     59 #ifdef MS_WINDOWS
     60 #define WCSTOK wcstok_s
     61 #else
     62 #define WCSTOK wcstok
     63 #endif
     64 
     65 /* For Py_GetArgcArgv(); set by main() */
     66 static wchar_t **orig_argv = NULL;
     67 static int orig_argc = 0;
     68 
     69 /* command line options */
     70 #define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
     71 
     72 #define PROGRAM_OPTS BASE_OPTS
     73 
     74 static const _PyOS_LongOption longoptions[] = {
     75     {L"check-hash-based-pycs", 1, 0},
     76     {NULL, 0, 0},
     77 };
     78 
     79 /* Short usage message (with %s for argv0) */
     80 static const char usage_line[] =
     81 "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
     82 
     83 /* Long usage message, split into parts < 512 bytes */
     84 static const char usage_1[] = "\
     85 Options and arguments (and corresponding environment variables):\n\
     86 -b     : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
     87          and comparing bytes/bytearray with str. (-bb: issue errors)\n\
     88 -B     : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
     89 -c cmd : program passed in as string (terminates option list)\n\
     90 -d     : debug output from parser; also PYTHONDEBUG=x\n\
     91 -E     : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
     92 -h     : print this help message and exit (also --help)\n\
     93 ";
     94 static const char usage_2[] = "\
     95 -i     : inspect interactively after running script; forces a prompt even\n\
     96          if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
     97 -I     : isolate Python from the user's environment (implies -E and -s)\n\
     98 -m mod : run library module as a script (terminates option list)\n\
     99 -O     : remove assert and __debug__-dependent statements; add .opt-1 before\n\
    100          .pyc extension; also PYTHONOPTIMIZE=x\n\
    101 -OO    : do -O changes and also discard docstrings; add .opt-2 before\n\
    102          .pyc extension\n\
    103 -q     : don't print version and copyright messages on interactive startup\n\
    104 -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
    105 -S     : don't imply 'import site' on initialization\n\
    106 ";
    107 static const char usage_3[] = "\
    108 -u     : force the stdout and stderr streams to be unbuffered;\n\
    109          this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
    110 -v     : verbose (trace import statements); also PYTHONVERBOSE=x\n\
    111          can be supplied multiple times to increase verbosity\n\
    112 -V     : print the Python version number and exit (also --version)\n\
    113          when given twice, print more information about the build\n\
    114 -W arg : warning control; arg is action:message:category:module:lineno\n\
    115          also PYTHONWARNINGS=arg\n\
    116 -x     : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
    117 -X opt : set implementation-specific option\n\
    118 --check-hash-based-pycs always|default|never:\n\
    119     control how Python invalidates hash-based .pyc files\n\
    120 ";
    121 static const char usage_4[] = "\
    122 file   : program read from script file\n\
    123 -      : program read from stdin (default; interactive mode if a tty)\n\
    124 arg ...: arguments passed to program in sys.argv[1:]\n\n\
    125 Other environment variables:\n\
    126 PYTHONSTARTUP: file executed on interactive startup (no default)\n\
    127 PYTHONPATH   : '%lc'-separated list of directories prefixed to the\n\
    128                default module search path.  The result is sys.path.\n\
    129 ";
    130 static const char usage_5[] =
    131 "PYTHONHOME   : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
    132 "               The default module search path uses %s.\n"
    133 "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
    134 "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
    135 "PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
    136 static const char usage_6[] =
    137 "PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
    138 "   to seed the hashes of str, bytes and datetime objects.  It can also be\n"
    139 "   set to an integer in the range [0,4294967295] to get hash values with a\n"
    140 "   predictable seed.\n"
    141 "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
    142 "   on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
    143 "   hooks.\n"
    144 "PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
    145 "   coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
    146 "   locale coercion and locale compatibility warnings on stderr.\n"
    147 "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
    148 "   debugger. It can be set to the callable of your debugger of choice.\n"
    149 "PYTHONDEVMODE: enable the development mode.\n";
    150 
    151 static void
    152 pymain_usage(int error, const wchar_t* program)
    153 {
    154     FILE *f = error ? stderr : stdout;
    155 
    156     fprintf(f, usage_line, program);
    157     if (error)
    158         fprintf(f, "Try `python -h' for more information.\n");
    159     else {
    160         fputs(usage_1, f);
    161         fputs(usage_2, f);
    162         fputs(usage_3, f);
    163         fprintf(f, usage_4, (wint_t)DELIM);
    164         fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
    165         fputs(usage_6, f);
    166     }
    167 }
    168 
    169 
    170 static const char*
    171 config_get_env_var(const char *name)
    172 {
    173     const char *var = Py_GETENV(name);
    174     if (var && var[0] != '\0') {
    175         return var;
    176     }
    177     else {
    178         return NULL;
    179     }
    180 }
    181 
    182 
    183 static int
    184 config_get_env_var_dup(wchar_t **dest, wchar_t *wname, char *name)
    185 {
    186     if (Py_IgnoreEnvironmentFlag) {
    187         *dest = NULL;
    188         return 0;
    189     }
    190 
    191 #ifdef MS_WINDOWS
    192     const wchar_t *var = _wgetenv(wname);
    193     if (!var || var[0] == '\0') {
    194         *dest = NULL;
    195         return 0;
    196     }
    197 
    198     wchar_t *copy = _PyMem_RawWcsdup(var);
    199     if (copy == NULL) {
    200         return -1;
    201     }
    202 
    203     *dest = copy;
    204 #else
    205     const char *var = getenv(name);
    206     if (!var || var[0] == '\0') {
    207         *dest = NULL;
    208         return 0;
    209     }
    210 
    211     size_t len;
    212     wchar_t *wvar = Py_DecodeLocale(var, &len);
    213     if (!wvar) {
    214         if (len == (size_t)-2) {
    215             return -2;
    216         }
    217         else {
    218             return -1;
    219         }
    220     }
    221     *dest = wvar;
    222 #endif
    223     return 0;
    224 }
    225 
    226 
    227 static void
    228 pymain_run_startup(PyCompilerFlags *cf)
    229 {
    230     const char *startup = config_get_env_var("PYTHONSTARTUP");
    231     if (startup == NULL) {
    232         return;
    233     }
    234 
    235     FILE *fp = _Py_fopen(startup, "r");
    236     if (fp == NULL) {
    237         int save_errno = errno;
    238         PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
    239         errno = save_errno;
    240 
    241         PyErr_SetFromErrnoWithFilename(PyExc_OSError,
    242                         startup);
    243         PyErr_Print();
    244         PyErr_Clear();
    245         return;
    246     }
    247 
    248     (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
    249     PyErr_Clear();
    250     fclose(fp);
    251 }
    252 
    253 static void
    254 pymain_run_interactive_hook(void)
    255 {
    256     PyObject *sys, *hook, *result;
    257     sys = PyImport_ImportModule("sys");
    258     if (sys == NULL) {
    259         goto error;
    260     }
    261 
    262     hook = PyObject_GetAttrString(sys, "__interactivehook__");
    263     Py_DECREF(sys);
    264     if (hook == NULL) {
    265         PyErr_Clear();
    266         return;
    267     }
    268 
    269     result = _PyObject_CallNoArg(hook);
    270     Py_DECREF(hook);
    271     if (result == NULL) {
    272         goto error;
    273     }
    274     Py_DECREF(result);
    275 
    276     return;
    277 
    278 error:
    279     PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
    280     PyErr_Print();
    281     PyErr_Clear();
    282 }
    283 
    284 
    285 static int
    286 pymain_run_module(const wchar_t *modname, int set_argv0)
    287 {
    288     PyObject *module, *runpy, *runmodule, *runargs, *result;
    289     runpy = PyImport_ImportModule("runpy");
    290     if (runpy == NULL) {
    291         fprintf(stderr, "Could not import runpy module\n");
    292         PyErr_Print();
    293         return -1;
    294     }
    295     runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
    296     if (runmodule == NULL) {
    297         fprintf(stderr, "Could not access runpy._run_module_as_main\n");
    298         PyErr_Print();
    299         Py_DECREF(runpy);
    300         return -1;
    301     }
    302     module = PyUnicode_FromWideChar(modname, wcslen(modname));
    303     if (module == NULL) {
    304         fprintf(stderr, "Could not convert module name to unicode\n");
    305         PyErr_Print();
    306         Py_DECREF(runpy);
    307         Py_DECREF(runmodule);
    308         return -1;
    309     }
    310     runargs = Py_BuildValue("(Oi)", module, set_argv0);
    311     if (runargs == NULL) {
    312         fprintf(stderr,
    313             "Could not create arguments for runpy._run_module_as_main\n");
    314         PyErr_Print();
    315         Py_DECREF(runpy);
    316         Py_DECREF(runmodule);
    317         Py_DECREF(module);
    318         return -1;
    319     }
    320     result = PyObject_Call(runmodule, runargs, NULL);
    321     if (result == NULL) {
    322         PyErr_Print();
    323     }
    324     Py_DECREF(runpy);
    325     Py_DECREF(runmodule);
    326     Py_DECREF(module);
    327     Py_DECREF(runargs);
    328     if (result == NULL) {
    329         return -1;
    330     }
    331     Py_DECREF(result);
    332     return 0;
    333 }
    334 
    335 static PyObject *
    336 pymain_get_importer(const wchar_t *filename)
    337 {
    338     PyObject *sys_path0 = NULL, *importer;
    339 
    340     sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename));
    341     if (sys_path0 == NULL) {
    342         goto error;
    343     }
    344 
    345     importer = PyImport_GetImporter(sys_path0);
    346     if (importer == NULL) {
    347         goto error;
    348     }
    349 
    350     if (importer == Py_None) {
    351         Py_DECREF(sys_path0);
    352         Py_DECREF(importer);
    353         return NULL;
    354     }
    355 
    356     Py_DECREF(importer);
    357     return sys_path0;
    358 
    359 error:
    360     Py_XDECREF(sys_path0);
    361     PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n");
    362     PyErr_Print();
    363     PyErr_Clear();
    364     return NULL;
    365 }
    366 
    367 
    368 static int
    369 pymain_run_command(wchar_t *command, PyCompilerFlags *cf)
    370 {
    371     PyObject *unicode, *bytes;
    372     int ret;
    373 
    374     unicode = PyUnicode_FromWideChar(command, -1);
    375     if (unicode == NULL) {
    376         goto error;
    377     }
    378 
    379     bytes = PyUnicode_AsUTF8String(unicode);
    380     Py_DECREF(unicode);
    381     if (bytes == NULL) {
    382         goto error;
    383     }
    384 
    385     ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf);
    386     Py_DECREF(bytes);
    387     return (ret != 0);
    388 
    389 error:
    390     PySys_WriteStderr("Unable to decode the command from the command line:\n");
    391     PyErr_Print();
    392     return 1;
    393 }
    394 
    395 
    396 static int
    397 pymain_run_file(FILE *fp, const wchar_t *filename, PyCompilerFlags *p_cf)
    398 {
    399     PyObject *unicode, *bytes = NULL;
    400     const char *filename_str;
    401     int run;
    402 
    403     /* call pending calls like signal handlers (SIGINT) */
    404     if (Py_MakePendingCalls() == -1) {
    405         PyErr_Print();
    406         return 1;
    407     }
    408 
    409     if (filename) {
    410         unicode = PyUnicode_FromWideChar(filename, wcslen(filename));
    411         if (unicode != NULL) {
    412             bytes = PyUnicode_EncodeFSDefault(unicode);
    413             Py_DECREF(unicode);
    414         }
    415         if (bytes != NULL) {
    416             filename_str = PyBytes_AsString(bytes);
    417         }
    418         else {
    419             PyErr_Clear();
    420             filename_str = "<encoding error>";
    421         }
    422     }
    423     else {
    424         filename_str = "<stdin>";
    425     }
    426 
    427     run = PyRun_AnyFileExFlags(fp, filename_str, filename != NULL, p_cf);
    428     Py_XDECREF(bytes);
    429     return run != 0;
    430 }
    431 
    432 
    433 /* Main program */
    434 
    435 typedef struct {
    436     wchar_t **argv;
    437     int nwarnoption;             /* Number of -W options */
    438     wchar_t **warnoptions;       /* -W options */
    439     int nenv_warnoption;         /* Number of PYTHONWARNINGS options */
    440     wchar_t **env_warnoptions;   /* PYTHONWARNINGS options */
    441     int print_help;              /* -h, -? options */
    442     int print_version;           /* -V option */
    443     int bytes_warning;           /* Py_BytesWarningFlag, -b */
    444     int debug;                   /* Py_DebugFlag, -b, PYTHONDEBUG */
    445     int inspect;                 /* Py_InspectFlag, -i, PYTHONINSPECT */
    446     int interactive;             /* Py_InteractiveFlag, -i */
    447     int isolated;                /* Py_IsolatedFlag, -I */
    448     int optimization_level;      /* Py_OptimizeFlag, -O, PYTHONOPTIMIZE */
    449     int dont_write_bytecode;     /* Py_DontWriteBytecodeFlag, -B, PYTHONDONTWRITEBYTECODE */
    450     int no_user_site_directory;  /* Py_NoUserSiteDirectory, -I, -s, PYTHONNOUSERSITE */
    451     int no_site_import;          /* Py_NoSiteFlag, -S */
    452     int use_unbuffered_io;       /* Py_UnbufferedStdioFlag, -u, PYTHONUNBUFFERED */
    453     int verbosity;               /* Py_VerboseFlag, -v, PYTHONVERBOSE */
    454     int quiet_flag;              /* Py_QuietFlag, -q */
    455     const char *check_hash_pycs_mode; /* --check-hash-based-pycs */
    456 #ifdef MS_WINDOWS
    457     int legacy_windows_fs_encoding;  /* Py_LegacyWindowsFSEncodingFlag,
    458                                         PYTHONLEGACYWINDOWSFSENCODING */
    459     int legacy_windows_stdio;        /* Py_LegacyWindowsStdioFlag,
    460                                         PYTHONLEGACYWINDOWSSTDIO */
    461 #endif
    462 } _PyCmdline;
    463 
    464 /* Structure used by Py_Main() to pass data to subfunctions */
    465 typedef struct {
    466     /* Input arguments */
    467     int argc;
    468     int use_bytes_argv;
    469     char **bytes_argv;
    470     wchar_t **wchar_argv;
    471 
    472     /* Exit status or "exit code": result of pymain_main() */
    473     int status;
    474     /* Error message if a function failed */
    475     _PyInitError err;
    476 
    477     /* non-zero is stdin is a TTY or if -i option is used */
    478     int stdin_is_interactive;
    479     int skip_first_line;         /* -x option */
    480     wchar_t *filename;           /* Trailing arg without -c or -m */
    481     wchar_t *command;            /* -c argument */
    482     wchar_t *module;             /* -m argument */
    483 
    484     PyObject *main_importer_path;
    485 } _PyMain;
    486 
    487 #define _PyMain_INIT {.err = _Py_INIT_OK()}
    488 /* Note: _PyMain_INIT sets other fields to 0/NULL */
    489 
    490 
    491 /* Non-zero if filename, command (-c) or module (-m) is set
    492    on the command line */
    493 #define RUN_CODE(pymain) \
    494     (pymain->command != NULL || pymain->filename != NULL \
    495      || pymain->module != NULL)
    496 
    497 
    498 static wchar_t*
    499 pymain_wstrdup(_PyMain *pymain, const wchar_t *str)
    500 {
    501     wchar_t *str2 = _PyMem_RawWcsdup(str);
    502     if (str2 == NULL) {
    503         pymain->err = _Py_INIT_NO_MEMORY();
    504         return NULL;
    505     }
    506     return str2;
    507 }
    508 
    509 
    510 static void
    511 clear_wstrlist(int len, wchar_t **list)
    512 {
    513     for (int i=0; i < len; i++) {
    514         PyMem_RawFree(list[i]);
    515     }
    516     PyMem_RawFree(list);
    517 }
    518 
    519 
    520 static int
    521 pymain_init_cmdline_argv(_PyMain *pymain, _PyCoreConfig *config,
    522                          _PyCmdline *cmdline)
    523 {
    524     assert(cmdline->argv == NULL);
    525 
    526     if (pymain->use_bytes_argv) {
    527         /* +1 for a the NULL terminator */
    528         size_t size = sizeof(wchar_t*) * (pymain->argc + 1);
    529         wchar_t** argv = (wchar_t **)PyMem_RawMalloc(size);
    530         if (argv == NULL) {
    531             pymain->err = _Py_INIT_NO_MEMORY();
    532             return -1;
    533         }
    534 
    535         for (int i = 0; i < pymain->argc; i++) {
    536             size_t len;
    537             wchar_t *arg = Py_DecodeLocale(pymain->bytes_argv[i], &len);
    538             if (arg == NULL) {
    539                 clear_wstrlist(i, argv);
    540                 pymain->err = DECODE_LOCALE_ERR("command line arguments",
    541                                                 (Py_ssize_t)len);
    542                 return -1;
    543             }
    544             argv[i] = arg;
    545         }
    546         argv[pymain->argc] = NULL;
    547 
    548         cmdline->argv = argv;
    549     }
    550     else {
    551         cmdline->argv = pymain->wchar_argv;
    552     }
    553 
    554     wchar_t *program;
    555     if (pymain->argc >= 1 && cmdline->argv != NULL) {
    556         program = cmdline->argv[0];
    557     }
    558     else {
    559         program = L"";
    560     }
    561     config->program = pymain_wstrdup(pymain, program);
    562     if (config->program == NULL) {
    563         return -1;
    564     }
    565 
    566     return 0;
    567 }
    568 
    569 
    570 static void
    571 pymain_clear_cmdline(_PyMain *pymain, _PyCmdline *cmdline)
    572 {
    573     PyMemAllocatorEx old_alloc;
    574     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    575 
    576     clear_wstrlist(cmdline->nwarnoption, cmdline->warnoptions);
    577     cmdline->nwarnoption = 0;
    578     cmdline->warnoptions = NULL;
    579 
    580     clear_wstrlist(cmdline->nenv_warnoption, cmdline->env_warnoptions);
    581     cmdline->nenv_warnoption = 0;
    582     cmdline->env_warnoptions = NULL;
    583 
    584     if (pymain->use_bytes_argv && cmdline->argv != NULL) {
    585         clear_wstrlist(pymain->argc, cmdline->argv);
    586     }
    587     cmdline->argv = NULL;
    588 
    589     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    590 }
    591 
    592 
    593 static void
    594 pymain_clear_pymain(_PyMain *pymain)
    595 {
    596 #define CLEAR(ATTR) \
    597     do { \
    598         PyMem_RawFree(ATTR); \
    599         ATTR = NULL; \
    600     } while (0)
    601 
    602     CLEAR(pymain->filename);
    603     CLEAR(pymain->command);
    604     CLEAR(pymain->module);
    605 #undef CLEAR
    606 }
    607 
    608 static void
    609 pymain_clear_config(_PyCoreConfig *config)
    610 {
    611     /* Clear core config with the memory allocator
    612        used by pymain_read_conf() */
    613     PyMemAllocatorEx old_alloc;
    614     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    615 
    616     _PyCoreConfig_Clear(config);
    617 
    618     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    619 }
    620 
    621 
    622 static void
    623 pymain_free_python(_PyMain *pymain)
    624 {
    625     Py_CLEAR(pymain->main_importer_path);
    626 
    627 #ifdef __INSURE__
    628     /* Insure++ is a memory analysis tool that aids in discovering
    629      * memory leaks and other memory problems.  On Python exit, the
    630      * interned string dictionaries are flagged as being in use at exit
    631      * (which it is).  Under normal circumstances, this is fine because
    632      * the memory will be automatically reclaimed by the system.  Under
    633      * memory debugging, it's a huge source of useless noise, so we
    634      * trade off slower shutdown for less distraction in the memory
    635      * reports.  -baw
    636      */
    637     _Py_ReleaseInternedUnicodeStrings();
    638 #endif /* __INSURE__ */
    639 }
    640 
    641 
    642 static void
    643 pymain_free_raw(_PyMain *pymain)
    644 {
    645     _PyImport_Fini2();
    646 
    647     /* Free global variables which cannot be freed in Py_Finalize():
    648        configuration options set before Py_Initialize() which should
    649        remain valid after Py_Finalize(), since
    650        Py_Initialize()-Py_Finalize() can be called multiple times. */
    651     _PyPathConfig_Clear(&_Py_path_config);
    652 
    653     /* Force the allocator used by pymain_read_conf() */
    654     PyMemAllocatorEx old_alloc;
    655     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    656 
    657     pymain_clear_pymain(pymain);
    658 
    659     clear_wstrlist(orig_argc, orig_argv);
    660     orig_argc = 0;
    661     orig_argv = NULL;
    662 
    663     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    664 }
    665 
    666 
    667 static void
    668 pymain_free(_PyMain *pymain)
    669 {
    670     pymain_free_python(pymain);
    671     pymain_free_raw(pymain);
    672 }
    673 
    674 
    675 static int
    676 pymain_run_main_from_importer(_PyMain *pymain)
    677 {
    678     /* Assume sys_path0 has already been checked by pymain_get_importer(),
    679      * so put it in sys.path[0] and import __main__ */
    680     PyObject *sys_path = PySys_GetObject("path");
    681     if (sys_path == NULL) {
    682         PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
    683         goto error;
    684     }
    685 
    686     if (PyList_Insert(sys_path, 0, pymain->main_importer_path)) {
    687         goto error;
    688     }
    689 
    690     int sts = pymain_run_module(L"__main__", 0);
    691     return (sts != 0);
    692 
    693 error:
    694     Py_CLEAR(pymain->main_importer_path);
    695     PyErr_Print();
    696     return 1;
    697 }
    698 
    699 
    700 static _PyInitError
    701 wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
    702 {
    703     wchar_t *str2 = _PyMem_RawWcsdup(str);
    704     if (str2 == NULL) {
    705         return _Py_INIT_NO_MEMORY();
    706     }
    707 
    708     size_t size = (*len + 1) * sizeof(list[0]);
    709     wchar_t **list2 = (wchar_t **)PyMem_RawRealloc(*list, size);
    710     if (list2 == NULL) {
    711         PyMem_RawFree(str2);
    712         return _Py_INIT_NO_MEMORY();
    713     }
    714     list2[*len] = str2;
    715     *list = list2;
    716     (*len)++;
    717     return _Py_INIT_OK();
    718 }
    719 
    720 
    721 static int
    722 pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str)
    723 {
    724     _PyInitError err = wstrlist_append(len, list, str);
    725     if (_Py_INIT_FAILED(err)) {
    726         pymain->err = err;
    727         return -1;
    728     }
    729     return 0;
    730 }
    731 
    732 
    733 /* Parse the command line arguments
    734    Return 0 on success.
    735    Return 1 if parsing failed.
    736    Set pymain->err and return -1 on other errors. */
    737 static int
    738 pymain_parse_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
    739                           _PyCmdline *cmdline)
    740 {
    741     _PyOS_ResetGetOpt();
    742     do {
    743         int longindex = -1;
    744         int c = _PyOS_GetOpt(pymain->argc, cmdline->argv, PROGRAM_OPTS,
    745                              longoptions, &longindex);
    746         if (c == EOF) {
    747             break;
    748         }
    749 
    750         if (c == 'c') {
    751             /* -c is the last option; following arguments
    752                that look like options are left for the
    753                command to interpret. */
    754             size_t len = wcslen(_PyOS_optarg) + 1 + 1;
    755             wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
    756             if (command == NULL) {
    757                 pymain->err = _Py_INIT_NO_MEMORY();
    758                 return -1;
    759             }
    760             memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
    761             command[len - 2] = '\n';
    762             command[len - 1] = 0;
    763             pymain->command = command;
    764             break;
    765         }
    766 
    767         if (c == 'm') {
    768             /* -m is the last option; following arguments
    769                that look like options are left for the
    770                module to interpret. */
    771             pymain->module = pymain_wstrdup(pymain, _PyOS_optarg);
    772             if (pymain->module == NULL) {
    773                 return -1;
    774             }
    775             break;
    776         }
    777 
    778         switch (c) {
    779         case 0:
    780             // Handle long option.
    781             assert(longindex == 0); // Only one long option now.
    782             if (!wcscmp(_PyOS_optarg, L"always")) {
    783                 cmdline->check_hash_pycs_mode = "always";
    784             } else if (!wcscmp(_PyOS_optarg, L"never")) {
    785                 cmdline->check_hash_pycs_mode = "never";
    786             } else if (!wcscmp(_PyOS_optarg, L"default")) {
    787                 cmdline->check_hash_pycs_mode = "default";
    788             } else {
    789                 fprintf(stderr, "--check-hash-based-pycs must be one of "
    790                         "'default', 'always', or 'never'\n");
    791                 return 1;
    792             }
    793             break;
    794 
    795         case 'b':
    796             cmdline->bytes_warning++;
    797             break;
    798 
    799         case 'd':
    800             cmdline->debug++;
    801             break;
    802 
    803         case 'i':
    804             cmdline->inspect++;
    805             cmdline->interactive++;
    806             break;
    807 
    808         case 'I':
    809             config->ignore_environment++;
    810             cmdline->isolated++;
    811             cmdline->no_user_site_directory++;
    812             break;
    813 
    814         /* case 'J': reserved for Jython */
    815 
    816         case 'O':
    817             cmdline->optimization_level++;
    818             break;
    819 
    820         case 'B':
    821             cmdline->dont_write_bytecode++;
    822             break;
    823 
    824         case 's':
    825             cmdline->no_user_site_directory++;
    826             break;
    827 
    828         case 'S':
    829             cmdline->no_site_import++;
    830             break;
    831 
    832         case 'E':
    833             config->ignore_environment++;
    834             break;
    835 
    836         case 't':
    837             /* ignored for backwards compatibility */
    838             break;
    839 
    840         case 'u':
    841             cmdline->use_unbuffered_io = 1;
    842             break;
    843 
    844         case 'v':
    845             cmdline->verbosity++;
    846             break;
    847 
    848         case 'x':
    849             pymain->skip_first_line = 1;
    850             break;
    851 
    852         case 'h':
    853         case '?':
    854             cmdline->print_help++;
    855             break;
    856 
    857         case 'V':
    858             cmdline->print_version++;
    859             break;
    860 
    861         case 'W':
    862             if (pymain_wstrlist_append(pymain,
    863                                        &cmdline->nwarnoption,
    864                                        &cmdline->warnoptions,
    865                                        _PyOS_optarg) < 0) {
    866                 return -1;
    867             }
    868             break;
    869 
    870         case 'X':
    871             if (pymain_wstrlist_append(pymain,
    872                                        &config->nxoption,
    873                                        &config->xoptions,
    874                                        _PyOS_optarg) < 0) {
    875                 return -1;
    876             }
    877             break;
    878 
    879         case 'q':
    880             cmdline->quiet_flag++;
    881             break;
    882 
    883         case 'R':
    884             config->use_hash_seed = 0;
    885             break;
    886 
    887         /* This space reserved for other options */
    888 
    889         default:
    890             /* unknown argument: parsing failed */
    891             return 1;
    892         }
    893     } while (1);
    894 
    895     if (pymain->command == NULL && pymain->module == NULL
    896         && _PyOS_optind < pymain->argc
    897         && wcscmp(cmdline->argv[_PyOS_optind], L"-") != 0)
    898     {
    899         pymain->filename = pymain_wstrdup(pymain, cmdline->argv[_PyOS_optind]);
    900         if (pymain->filename == NULL) {
    901             return -1;
    902         }
    903     }
    904 
    905     /* -c and -m options are exclusive */
    906     assert(!(pymain->command != NULL && pymain->module != NULL));
    907 
    908     return 0;
    909 }
    910 
    911 
    912 static int
    913 add_xoption(PyObject *opts, const wchar_t *s)
    914 {
    915     PyObject *name, *value;
    916 
    917     const wchar_t *name_end = wcschr(s, L'=');
    918     if (!name_end) {
    919         name = PyUnicode_FromWideChar(s, -1);
    920         value = Py_True;
    921         Py_INCREF(value);
    922     }
    923     else {
    924         name = PyUnicode_FromWideChar(s, name_end - s);
    925         value = PyUnicode_FromWideChar(name_end + 1, -1);
    926     }
    927     if (name == NULL || value == NULL) {
    928         goto error;
    929     }
    930     if (PyDict_SetItem(opts, name, value) < 0) {
    931         goto error;
    932     }
    933     Py_DECREF(name);
    934     Py_DECREF(value);
    935     return 0;
    936 
    937 error:
    938     Py_XDECREF(name);
    939     Py_XDECREF(value);
    940     return -1;
    941 }
    942 
    943 
    944 static PyObject*
    945 config_create_xoptions_dict(const _PyCoreConfig *config)
    946 {
    947     int nxoption = config->nxoption;
    948     wchar_t **xoptions = config->xoptions;
    949     PyObject *dict = PyDict_New();
    950     if (dict == NULL) {
    951         return NULL;
    952     }
    953 
    954     for (int i=0; i < nxoption; i++) {
    955         wchar_t *option = xoptions[i];
    956         if (add_xoption(dict, option) < 0) {
    957             Py_DECREF(dict);
    958             return NULL;
    959         }
    960     }
    961 
    962     return dict;
    963 }
    964 
    965 
    966 static _PyInitError
    967 config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)
    968 {
    969     for (int i = 0; i < len; i++) {
    970         _PyInitError err = wstrlist_append(&config->nwarnoption,
    971                                            &config->warnoptions,
    972                                            options[i]);
    973         if (_Py_INIT_FAILED(err)) {
    974             return err;
    975         }
    976     }
    977     return _Py_INIT_OK();
    978 }
    979 
    980 
    981 static _PyInitError
    982 config_init_warnoptions(_PyCoreConfig *config, _PyCmdline *cmdline)
    983 {
    984     _PyInitError err;
    985 
    986     assert(config->nwarnoption == 0);
    987 
    988     /* The priority order for warnings configuration is (highest precedence
    989      * first):
    990      *
    991      * - the BytesWarning filter, if needed ('-b', '-bb')
    992      * - any '-W' command line options; then
    993      * - the 'PYTHONWARNINGS' environment variable; then
    994      * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
    995      * - any implicit filters added by _warnings.c/warnings.py
    996      *
    997      * All settings except the last are passed to the warnings module via
    998      * the `sys.warnoptions` list. Since the warnings module works on the basis
    999      * of "the most recently added filter will be checked first", we add
   1000      * the lowest precedence entries first so that later entries override them.
   1001      */
   1002 
   1003     if (config->dev_mode) {
   1004         err = wstrlist_append(&config->nwarnoption,
   1005                               &config->warnoptions,
   1006                               L"default");
   1007         if (_Py_INIT_FAILED(err)) {
   1008             return err;
   1009         }
   1010     }
   1011 
   1012     err = config_add_warnings_optlist(config,
   1013                                       cmdline->nenv_warnoption,
   1014                                       cmdline->env_warnoptions);
   1015     if (_Py_INIT_FAILED(err)) {
   1016         return err;
   1017     }
   1018 
   1019     err = config_add_warnings_optlist(config,
   1020                                       cmdline->nwarnoption,
   1021                                       cmdline->warnoptions);
   1022     if (_Py_INIT_FAILED(err)) {
   1023         return err;
   1024     }
   1025 
   1026     /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
   1027      * don't even try to emit a warning, so we skip setting the filter in that
   1028      * case.
   1029      */
   1030     if (cmdline->bytes_warning) {
   1031         wchar_t *filter;
   1032         if (cmdline->bytes_warning> 1) {
   1033             filter = L"error::BytesWarning";
   1034         }
   1035         else {
   1036             filter = L"default::BytesWarning";
   1037         }
   1038         err = wstrlist_append(&config->nwarnoption,
   1039                               &config->warnoptions,
   1040                               filter);
   1041         if (_Py_INIT_FAILED(err)) {
   1042             return err;
   1043         }
   1044     }
   1045     return _Py_INIT_OK();
   1046 }
   1047 
   1048 
   1049 /* Get warning options from PYTHONWARNINGS environment variable.
   1050    Return 0 on success.
   1051    Set pymain->err and return -1 on error. */
   1052 static _PyInitError
   1053 cmdline_init_env_warnoptions(_PyCmdline *cmdline)
   1054 {
   1055     if (Py_IgnoreEnvironmentFlag) {
   1056         return _Py_INIT_OK();
   1057     }
   1058 
   1059     wchar_t *env;
   1060     int res = config_get_env_var_dup(&env, L"PYTHONWARNINGS", "PYTHONWARNINGS");
   1061     if (res < 0) {
   1062         return DECODE_LOCALE_ERR("PYTHONWARNINGS", res);
   1063     }
   1064 
   1065     if (env == NULL) {
   1066         return _Py_INIT_OK();
   1067     }
   1068 
   1069 
   1070     wchar_t *warning, *context = NULL;
   1071     for (warning = WCSTOK(env, L",", &context);
   1072          warning != NULL;
   1073          warning = WCSTOK(NULL, L",", &context))
   1074     {
   1075         _PyInitError err = wstrlist_append(&cmdline->nenv_warnoption,
   1076                                            &cmdline->env_warnoptions,
   1077                                           warning);
   1078         if (_Py_INIT_FAILED(err)) {
   1079             PyMem_RawFree(env);
   1080             return err;
   1081         }
   1082     }
   1083     PyMem_RawFree(env);
   1084     return _Py_INIT_OK();
   1085 }
   1086 
   1087 
   1088 static void
   1089 pymain_init_stdio(_PyMain *pymain)
   1090 {
   1091     pymain->stdin_is_interactive = (isatty(fileno(stdin))
   1092                                     || Py_InteractiveFlag);
   1093 
   1094 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
   1095     /* don't translate newlines (\r\n <=> \n) */
   1096     _setmode(fileno(stdin), O_BINARY);
   1097     _setmode(fileno(stdout), O_BINARY);
   1098     _setmode(fileno(stderr), O_BINARY);
   1099 #endif
   1100 
   1101     if (Py_UnbufferedStdioFlag) {
   1102 #ifdef HAVE_SETVBUF
   1103         setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
   1104         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
   1105         setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
   1106 #else /* !HAVE_SETVBUF */
   1107         setbuf(stdin,  (char *)NULL);
   1108         setbuf(stdout, (char *)NULL);
   1109         setbuf(stderr, (char *)NULL);
   1110 #endif /* !HAVE_SETVBUF */
   1111     }
   1112     else if (Py_InteractiveFlag) {
   1113 #ifdef MS_WINDOWS
   1114         /* Doesn't have to have line-buffered -- use unbuffered */
   1115         /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
   1116         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
   1117 #else /* !MS_WINDOWS */
   1118 #ifdef HAVE_SETVBUF
   1119         setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
   1120         setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
   1121 #endif /* HAVE_SETVBUF */
   1122 #endif /* !MS_WINDOWS */
   1123         /* Leave stderr alone - it should be unbuffered anyway. */
   1124     }
   1125 }
   1126 
   1127 
   1128 /* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
   1129    environment variables on macOS if available. */
   1130 static _PyInitError
   1131 config_init_program_name(_PyCoreConfig *config)
   1132 {
   1133     assert(config->program_name == NULL);
   1134 
   1135     /* If Py_SetProgramName() was called, use its value */
   1136     const wchar_t *program_name = _Py_path_config.program_name;
   1137     if (program_name != NULL) {
   1138         config->program_name = _PyMem_RawWcsdup(program_name);
   1139         if (config->program_name == NULL) {
   1140             return _Py_INIT_NO_MEMORY();
   1141         }
   1142         return _Py_INIT_OK();
   1143     }
   1144 
   1145 #ifdef __APPLE__
   1146     /* On MacOS X, when the Python interpreter is embedded in an
   1147        application bundle, it gets executed by a bootstrapping script
   1148        that does os.execve() with an argv[0] that's different from the
   1149        actual Python executable. This is needed to keep the Finder happy,
   1150        or rather, to work around Apple's overly strict requirements of
   1151        the process name. However, we still need a usable sys.executable,
   1152        so the actual executable path is passed in an environment variable.
   1153        See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
   1154        script. */
   1155     const char *p = config_get_env_var("PYTHONEXECUTABLE");
   1156     if (p != NULL) {
   1157         size_t len;
   1158         wchar_t* program_name = Py_DecodeLocale(p, &len);
   1159         if (program_name == NULL) {
   1160             return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment "
   1161                                      "variable", (Py_ssize_t)len);
   1162         }
   1163         config->program_name = program_name;
   1164         return _Py_INIT_OK();
   1165     }
   1166 #ifdef WITH_NEXT_FRAMEWORK
   1167     else {
   1168         const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
   1169         if (pyvenv_launcher && *pyvenv_launcher) {
   1170             /* Used by Mac/Tools/pythonw.c to forward
   1171              * the argv0 of the stub executable
   1172              */
   1173             size_t len;
   1174             wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
   1175             if (program_name == NULL) {
   1176                 return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment "
   1177                                          "variable", (Py_ssize_t)len);
   1178             }
   1179             config->program_name = program_name;
   1180             return _Py_INIT_OK();
   1181         }
   1182     }
   1183 #endif   /* WITH_NEXT_FRAMEWORK */
   1184 #endif   /* __APPLE__ */
   1185 
   1186     /* Use argv[0] by default, if available */
   1187     if (config->program != NULL) {
   1188         config->program_name = _PyMem_RawWcsdup(config->program);
   1189         if (config->program_name == NULL) {
   1190             return _Py_INIT_NO_MEMORY();
   1191         }
   1192         return _Py_INIT_OK();
   1193     }
   1194 
   1195     /* Last fall back: hardcoded string */
   1196 #ifdef MS_WINDOWS
   1197     const wchar_t *default_program_name = L"python";
   1198 #else
   1199     const wchar_t *default_program_name = L"python3";
   1200 #endif
   1201     config->program_name = _PyMem_RawWcsdup(default_program_name);
   1202     if (config->program_name == NULL) {
   1203         return _Py_INIT_NO_MEMORY();
   1204     }
   1205     return _Py_INIT_OK();
   1206 }
   1207 
   1208 
   1209 static _PyInitError
   1210 config_init_executable(_PyCoreConfig *config)
   1211 {
   1212     assert(config->executable == NULL);
   1213 
   1214     /* If Py_SetProgramFullPath() was called, use its value */
   1215     const wchar_t *program_full_path = _Py_path_config.program_full_path;
   1216     if (program_full_path != NULL) {
   1217         config->executable = _PyMem_RawWcsdup(program_full_path);
   1218         if (config->executable == NULL) {
   1219             return _Py_INIT_NO_MEMORY();
   1220         }
   1221         return _Py_INIT_OK();
   1222     }
   1223 
   1224     return _Py_INIT_OK();
   1225 }
   1226 
   1227 
   1228 static void
   1229 pymain_header(_PyMain *pymain)
   1230 {
   1231     if (Py_QuietFlag) {
   1232         return;
   1233     }
   1234 
   1235     if (!Py_VerboseFlag && (RUN_CODE(pymain) || !pymain->stdin_is_interactive)) {
   1236         return;
   1237     }
   1238 
   1239     fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
   1240     if (!Py_NoSiteFlag) {
   1241         fprintf(stderr, "%s\n", COPYRIGHT);
   1242     }
   1243 }
   1244 
   1245 
   1246 static wchar_t**
   1247 copy_wstrlist(int len, wchar_t **list)
   1248 {
   1249     assert((len > 0 && list != NULL) || len == 0);
   1250     size_t size = len * sizeof(list[0]);
   1251     wchar_t **list_copy = PyMem_RawMalloc(size);
   1252     if (list_copy == NULL) {
   1253         return NULL;
   1254     }
   1255     for (int i=0; i < len; i++) {
   1256         wchar_t* arg = _PyMem_RawWcsdup(list[i]);
   1257         if (arg == NULL) {
   1258             clear_wstrlist(i, list_copy);
   1259             return NULL;
   1260         }
   1261         list_copy[i] = arg;
   1262     }
   1263     return list_copy;
   1264 }
   1265 
   1266 
   1267 static int
   1268 pymain_init_core_argv(_PyMain *pymain, _PyCoreConfig *config,
   1269                       _PyCmdline *cmdline)
   1270 {
   1271     /* Copy argv to be able to modify it (to force -c/-m) */
   1272     int argc = pymain->argc - _PyOS_optind;
   1273     wchar_t **argv;
   1274 
   1275     if (argc <= 0 || cmdline->argv == NULL) {
   1276         /* Ensure at least one (empty) argument is seen */
   1277         static wchar_t *empty_argv[1] = {L""};
   1278         argc = 1;
   1279         argv = copy_wstrlist(1, empty_argv);
   1280     }
   1281     else {
   1282         argv = copy_wstrlist(argc, &cmdline->argv[_PyOS_optind]);
   1283     }
   1284 
   1285     if (argv == NULL) {
   1286         pymain->err = _Py_INIT_NO_MEMORY();
   1287         return -1;
   1288     }
   1289 
   1290     wchar_t *arg0 = NULL;
   1291     if (pymain->command != NULL) {
   1292         /* Force sys.argv[0] = '-c' */
   1293         arg0 = L"-c";
   1294     }
   1295     else if (pymain->module != NULL) {
   1296         /* Force sys.argv[0] = '-m'*/
   1297         arg0 = L"-m";
   1298     }
   1299     if (arg0 != NULL) {
   1300         arg0 = _PyMem_RawWcsdup(arg0);
   1301         if (arg0 == NULL) {
   1302             clear_wstrlist(argc, argv);
   1303             pymain->err = _Py_INIT_NO_MEMORY();
   1304             return -1;
   1305         }
   1306 
   1307         assert(argc >= 1);
   1308         PyMem_RawFree(argv[0]);
   1309         argv[0] = arg0;
   1310     }
   1311 
   1312     config->argc = argc;
   1313     config->argv = argv;
   1314     return 0;
   1315 }
   1316 
   1317 
   1318 static PyObject*
   1319 _Py_wstrlist_as_pylist(int len, wchar_t **list)
   1320 {
   1321     assert(list != NULL || len < 1);
   1322 
   1323     PyObject *pylist = PyList_New(len);
   1324     if (pylist == NULL) {
   1325         return NULL;
   1326     }
   1327 
   1328     for (int i = 0; i < len; i++) {
   1329         PyObject *v = PyUnicode_FromWideChar(list[i], -1);
   1330         if (v == NULL) {
   1331             Py_DECREF(pylist);
   1332             return NULL;
   1333         }
   1334         PyList_SET_ITEM(pylist, i, v);
   1335     }
   1336     return pylist;
   1337 }
   1338 
   1339 
   1340 static int
   1341 pymain_compute_path0(_PyMain *pymain, _PyCoreConfig *config, PyObject **path0)
   1342 {
   1343     if (pymain->main_importer_path != NULL) {
   1344         /* Let pymain_run_main_from_importer() adjust sys.path[0] later */
   1345         *path0 = NULL;
   1346         return 0;
   1347     }
   1348 
   1349     if (Py_IsolatedFlag) {
   1350         *path0 = NULL;
   1351         return 0;
   1352     }
   1353 
   1354     *path0 = _PyPathConfig_ComputeArgv0(config->argc, config->argv);
   1355     if (*path0 == NULL) {
   1356         pymain->err = _Py_INIT_NO_MEMORY();
   1357         return -1;
   1358     }
   1359     return 0;
   1360 }
   1361 
   1362 
   1363 static int
   1364 pymain_update_sys_path(_PyMain *pymain, PyObject *path0)
   1365 {
   1366     /* Prepend argv[0] to sys.path.
   1367        If argv[0] is a symlink, use the real path. */
   1368     PyObject *sys_path = PySys_GetObject("path");
   1369     if (sys_path == NULL) {
   1370         pymain->err = _Py_INIT_ERR("can't get sys.path");
   1371         return -1;
   1372     }
   1373 
   1374     /* Prepend path0 to sys.path */
   1375     if (PyList_Insert(sys_path, 0, path0) < 0) {
   1376         pymain->err = _Py_INIT_ERR("sys.path.insert(0, path0) failed");
   1377         return -1;
   1378     }
   1379     return 0;
   1380 }
   1381 
   1382 
   1383 PyObject *
   1384 _Py_GetGlobalVariablesAsDict(void)
   1385 {
   1386     PyObject *dict, *obj;
   1387 
   1388     dict = PyDict_New();
   1389     if (dict == NULL) {
   1390         return NULL;
   1391     }
   1392 
   1393 #define SET_ITEM(KEY, EXPR) \
   1394         do { \
   1395             obj = (EXPR); \
   1396             if (obj == NULL) { \
   1397                 return NULL; \
   1398             } \
   1399             int res = PyDict_SetItemString(dict, (KEY), obj); \
   1400             Py_DECREF(obj); \
   1401             if (res < 0) { \
   1402                 goto fail; \
   1403             } \
   1404         } while (0)
   1405 #define SET_ITEM_INT(VAR) \
   1406     SET_ITEM(#VAR, PyLong_FromLong(VAR))
   1407 #define FROM_STRING(STR) \
   1408     ((STR != NULL) ? \
   1409         PyUnicode_FromString(STR) \
   1410         : (Py_INCREF(Py_None), Py_None))
   1411 #define SET_ITEM_STR(VAR) \
   1412     SET_ITEM(#VAR, FROM_STRING(VAR))
   1413 
   1414     SET_ITEM_STR(Py_FileSystemDefaultEncoding);
   1415     SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
   1416     SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
   1417 
   1418     SET_ITEM_INT(Py_UTF8Mode);
   1419     SET_ITEM_INT(Py_DebugFlag);
   1420     SET_ITEM_INT(Py_VerboseFlag);
   1421     SET_ITEM_INT(Py_QuietFlag);
   1422     SET_ITEM_INT(Py_InteractiveFlag);
   1423     SET_ITEM_INT(Py_InspectFlag);
   1424 
   1425     SET_ITEM_INT(Py_OptimizeFlag);
   1426     SET_ITEM_INT(Py_NoSiteFlag);
   1427     SET_ITEM_INT(Py_BytesWarningFlag);
   1428     SET_ITEM_INT(Py_FrozenFlag);
   1429     SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
   1430     SET_ITEM_INT(Py_DontWriteBytecodeFlag);
   1431     SET_ITEM_INT(Py_NoUserSiteDirectory);
   1432     SET_ITEM_INT(Py_UnbufferedStdioFlag);
   1433     SET_ITEM_INT(Py_HashRandomizationFlag);
   1434     SET_ITEM_INT(Py_IsolatedFlag);
   1435 
   1436 #ifdef MS_WINDOWS
   1437     SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
   1438     SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
   1439 #endif
   1440 
   1441     return dict;
   1442 
   1443 fail:
   1444     Py_DECREF(dict);
   1445     return NULL;
   1446 
   1447 #undef FROM_STRING
   1448 #undef SET_ITEM
   1449 #undef SET_ITEM_INT
   1450 #undef SET_ITEM_STR
   1451 }
   1452 
   1453 
   1454 void
   1455 _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
   1456 {
   1457 #define COPY_FLAG(ATTR, VALUE) \
   1458         if (config->ATTR == -1) { \
   1459             config->ATTR = VALUE; \
   1460         }
   1461 
   1462     COPY_FLAG(ignore_environment, Py_IgnoreEnvironmentFlag);
   1463     COPY_FLAG(utf8_mode, Py_UTF8Mode);
   1464 
   1465 #undef COPY_FLAG
   1466 }
   1467 
   1468 
   1469 /* Get Py_xxx global configuration variables */
   1470 static void
   1471 cmdline_get_global_config(_PyCmdline *cmdline)
   1472 {
   1473     cmdline->bytes_warning = Py_BytesWarningFlag;
   1474     cmdline->debug = Py_DebugFlag;
   1475     cmdline->inspect = Py_InspectFlag;
   1476     cmdline->interactive = Py_InteractiveFlag;
   1477     cmdline->isolated = Py_IsolatedFlag;
   1478     cmdline->optimization_level = Py_OptimizeFlag;
   1479     cmdline->dont_write_bytecode = Py_DontWriteBytecodeFlag;
   1480     cmdline->no_user_site_directory = Py_NoUserSiteDirectory;
   1481     cmdline->no_site_import = Py_NoSiteFlag;
   1482     cmdline->use_unbuffered_io = Py_UnbufferedStdioFlag;
   1483     cmdline->verbosity = Py_VerboseFlag;
   1484     cmdline->quiet_flag = Py_QuietFlag;
   1485 #ifdef MS_WINDOWS
   1486     cmdline->legacy_windows_fs_encoding = Py_LegacyWindowsFSEncodingFlag;
   1487     cmdline->legacy_windows_stdio = Py_LegacyWindowsStdioFlag;
   1488 #endif
   1489     cmdline->check_hash_pycs_mode = _Py_CheckHashBasedPycsMode ;
   1490 }
   1491 
   1492 
   1493 void
   1494 _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
   1495 {
   1496     Py_IgnoreEnvironmentFlag = config->ignore_environment;
   1497     Py_UTF8Mode = config->utf8_mode;
   1498 
   1499     /* Random or non-zero hash seed */
   1500     Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
   1501                                 config->hash_seed != 0);
   1502 }
   1503 
   1504 
   1505 /* Set Py_xxx global configuration variables */
   1506 static void
   1507 cmdline_set_global_config(_PyCmdline *cmdline)
   1508 {
   1509     Py_BytesWarningFlag = cmdline->bytes_warning;
   1510     Py_DebugFlag = cmdline->debug;
   1511     Py_InspectFlag = cmdline->inspect;
   1512     Py_InteractiveFlag = cmdline->interactive;
   1513     Py_IsolatedFlag = cmdline->isolated;
   1514     Py_OptimizeFlag = cmdline->optimization_level;
   1515     Py_DontWriteBytecodeFlag = cmdline->dont_write_bytecode;
   1516     Py_NoUserSiteDirectory = cmdline->no_user_site_directory;
   1517     Py_NoSiteFlag = cmdline->no_site_import;
   1518     Py_UnbufferedStdioFlag = cmdline->use_unbuffered_io;
   1519     Py_VerboseFlag = cmdline->verbosity;
   1520     Py_QuietFlag = cmdline->quiet_flag;
   1521     _Py_CheckHashBasedPycsMode = cmdline->check_hash_pycs_mode;
   1522 #ifdef MS_WINDOWS
   1523     Py_LegacyWindowsFSEncodingFlag = cmdline->legacy_windows_fs_encoding;
   1524     Py_LegacyWindowsStdioFlag = cmdline->legacy_windows_stdio;
   1525 #endif
   1526 }
   1527 
   1528 
   1529 static void
   1530 pymain_import_readline(_PyMain *pymain)
   1531 {
   1532     if (Py_IsolatedFlag) {
   1533         return;
   1534     }
   1535     if (!Py_InspectFlag && RUN_CODE(pymain)) {
   1536         return;
   1537     }
   1538     if (!isatty(fileno(stdin))) {
   1539         return;
   1540     }
   1541 
   1542     PyObject *mod = PyImport_ImportModule("readline");
   1543     if (mod == NULL) {
   1544         PyErr_Clear();
   1545     }
   1546     else {
   1547         Py_DECREF(mod);
   1548     }
   1549 }
   1550 
   1551 
   1552 static FILE*
   1553 pymain_open_filename(_PyMain *pymain)
   1554 {
   1555     const _PyCoreConfig *config = &_PyGILState_GetInterpreterStateUnsafe()->core_config;
   1556     FILE* fp;
   1557 
   1558     fp = _Py_wfopen(pymain->filename, L"r");
   1559     if (fp == NULL) {
   1560         char *cfilename_buffer;
   1561         const char *cfilename;
   1562         int err = errno;
   1563         cfilename_buffer = _Py_EncodeLocaleRaw(pymain->filename, NULL);
   1564         if (cfilename_buffer != NULL)
   1565             cfilename = cfilename_buffer;
   1566         else
   1567             cfilename = "<unprintable file name>";
   1568         fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
   1569                 config->program, cfilename, err, strerror(err));
   1570         PyMem_RawFree(cfilename_buffer);
   1571         pymain->status = 2;
   1572         return NULL;
   1573     }
   1574 
   1575     if (pymain->skip_first_line) {
   1576         int ch;
   1577         /* Push back first newline so line numbers
   1578            remain the same */
   1579         while ((ch = getc(fp)) != EOF) {
   1580             if (ch == '\n') {
   1581                 (void)ungetc(ch, fp);
   1582                 break;
   1583             }
   1584         }
   1585     }
   1586 
   1587     struct _Py_stat_struct sb;
   1588     if (_Py_fstat_noraise(fileno(fp), &sb) == 0 &&
   1589             S_ISDIR(sb.st_mode)) {
   1590         fprintf(stderr,
   1591                 "%ls: '%ls' is a directory, cannot continue\n",
   1592                 config->program, pymain->filename);
   1593         fclose(fp);
   1594         pymain->status = 1;
   1595         return NULL;
   1596     }
   1597 
   1598     return fp;
   1599 }
   1600 
   1601 
   1602 static void
   1603 pymain_run_filename(_PyMain *pymain, PyCompilerFlags *cf)
   1604 {
   1605     if (pymain->filename == NULL && pymain->stdin_is_interactive) {
   1606         Py_InspectFlag = 0; /* do exit on SystemExit */
   1607         pymain_run_startup(cf);
   1608         pymain_run_interactive_hook();
   1609     }
   1610 
   1611     if (pymain->main_importer_path != NULL) {
   1612         pymain->status = pymain_run_main_from_importer(pymain);
   1613         return;
   1614     }
   1615 
   1616     FILE *fp;
   1617     if (pymain->filename != NULL) {
   1618         fp = pymain_open_filename(pymain);
   1619         if (fp == NULL) {
   1620             return;
   1621         }
   1622     }
   1623     else {
   1624         fp = stdin;
   1625     }
   1626 
   1627     pymain->status = pymain_run_file(fp, pymain->filename, cf);
   1628 }
   1629 
   1630 
   1631 static void
   1632 pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
   1633 {
   1634     /* Check this environment variable at the end, to give programs the
   1635        opportunity to set it from Python. */
   1636     if (!Py_InspectFlag && config_get_env_var("PYTHONINSPECT")) {
   1637         Py_InspectFlag = 1;
   1638     }
   1639 
   1640     if (!(Py_InspectFlag && pymain->stdin_is_interactive && RUN_CODE(pymain))) {
   1641         return;
   1642     }
   1643 
   1644     Py_InspectFlag = 0;
   1645     pymain_run_interactive_hook();
   1646 
   1647     int res = PyRun_AnyFileFlags(stdin, "<stdin>", cf);
   1648     pymain->status = (res != 0);
   1649 }
   1650 
   1651 
   1652 /* Parse the command line.
   1653    Handle --version and --help options directly.
   1654 
   1655    Return 1 if Python must exit.
   1656    Return 0 on success.
   1657    Set pymain->err and return -1 on failure. */
   1658 static int
   1659 pymain_parse_cmdline(_PyMain *pymain, _PyCoreConfig *config,
   1660                      _PyCmdline *cmdline)
   1661 {
   1662     int res = pymain_parse_cmdline_impl(pymain, config, cmdline);
   1663     if (res < 0) {
   1664         return -1;
   1665     }
   1666     if (res) {
   1667         pymain_usage(1, config->program);
   1668         pymain->status = 2;
   1669         return 1;
   1670     }
   1671 
   1672     if (pymain->command != NULL || pymain->module != NULL) {
   1673         /* Backup _PyOS_optind */
   1674         _PyOS_optind--;
   1675     }
   1676 
   1677     return 0;
   1678 }
   1679 
   1680 
   1681 static const wchar_t*
   1682 config_get_xoption(_PyCoreConfig *config, wchar_t *name)
   1683 {
   1684     int nxoption = config->nxoption;
   1685     wchar_t **xoptions = config->xoptions;
   1686     for (int i=0; i < nxoption; i++) {
   1687         wchar_t *option = xoptions[i];
   1688         size_t len;
   1689         wchar_t *sep = wcschr(option, L'=');
   1690         if (sep != NULL) {
   1691             len = (sep - option);
   1692         }
   1693         else {
   1694             len = wcslen(option);
   1695         }
   1696         if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
   1697             return option;
   1698         }
   1699     }
   1700     return NULL;
   1701 }
   1702 
   1703 
   1704 static int
   1705 pymain_str_to_int(const char *str, int *result)
   1706 {
   1707     errno = 0;
   1708     const char *endptr = str;
   1709     long value = strtol(str, (char **)&endptr, 10);
   1710     if (*endptr != '\0' || errno == ERANGE) {
   1711         return -1;
   1712     }
   1713     if (value < INT_MIN || value > INT_MAX) {
   1714         return -1;
   1715     }
   1716 
   1717     *result = (int)value;
   1718     return 0;
   1719 }
   1720 
   1721 
   1722 static int
   1723 pymain_wstr_to_int(const wchar_t *wstr, int *result)
   1724 {
   1725     errno = 0;
   1726     const wchar_t *endptr = wstr;
   1727     long value = wcstol(wstr, (wchar_t **)&endptr, 10);
   1728     if (*endptr != '\0' || errno == ERANGE) {
   1729         return -1;
   1730     }
   1731     if (value < INT_MIN || value > INT_MAX) {
   1732         return -1;
   1733     }
   1734 
   1735     *result = (int)value;
   1736     return 0;
   1737 }
   1738 
   1739 
   1740 static _PyInitError
   1741 config_init_tracemalloc(_PyCoreConfig *config)
   1742 {
   1743     int nframe;
   1744     int valid;
   1745 
   1746     const char *env = config_get_env_var("PYTHONTRACEMALLOC");
   1747     if (env) {
   1748         if (!pymain_str_to_int(env, &nframe)) {
   1749             valid = (nframe >= 1);
   1750         }
   1751         else {
   1752             valid = 0;
   1753         }
   1754         if (!valid) {
   1755             return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
   1756                                      "of frames");
   1757         }
   1758         config->tracemalloc = nframe;
   1759     }
   1760 
   1761     const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
   1762     if (xoption) {
   1763         const wchar_t *sep = wcschr(xoption, L'=');
   1764         if (sep) {
   1765             if (!pymain_wstr_to_int(sep + 1, &nframe)) {
   1766                 valid = (nframe >= 1);
   1767             }
   1768             else {
   1769                 valid = 0;
   1770             }
   1771             if (!valid) {
   1772                 return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
   1773                                          "invalid number of frames");
   1774             }
   1775         }
   1776         else {
   1777             /* -X tracemalloc behaves as -X tracemalloc=1 */
   1778             nframe = 1;
   1779         }
   1780         config->tracemalloc = nframe;
   1781     }
   1782     return _Py_INIT_OK();
   1783 }
   1784 
   1785 
   1786 static void
   1787 get_env_flag(int *flag, const char *name)
   1788 {
   1789     const char *var = config_get_env_var(name);
   1790     if (!var) {
   1791         return;
   1792     }
   1793     int value;
   1794     if (pymain_str_to_int(var, &value) < 0 || value < 0) {
   1795         /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
   1796         value = 1;
   1797     }
   1798     if (*flag < value) {
   1799         *flag = value;
   1800     }
   1801 }
   1802 
   1803 
   1804 static void
   1805 cmdline_get_env_flags(_PyCmdline *cmdline)
   1806 {
   1807     get_env_flag(&cmdline->debug, "PYTHONDEBUG");
   1808     get_env_flag(&cmdline->verbosity, "PYTHONVERBOSE");
   1809     get_env_flag(&cmdline->optimization_level, "PYTHONOPTIMIZE");
   1810     get_env_flag(&cmdline->inspect, "PYTHONINSPECT");
   1811     get_env_flag(&cmdline->dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
   1812     get_env_flag(&cmdline->no_user_site_directory, "PYTHONNOUSERSITE");
   1813     get_env_flag(&cmdline->use_unbuffered_io, "PYTHONUNBUFFERED");
   1814 #ifdef MS_WINDOWS
   1815     get_env_flag(&cmdline->legacy_windows_fs_encoding,
   1816                  "PYTHONLEGACYWINDOWSFSENCODING");
   1817     get_env_flag(&cmdline->legacy_windows_stdio,
   1818                  "PYTHONLEGACYWINDOWSSTDIO");
   1819 #endif
   1820 }
   1821 
   1822 
   1823 /* Set global variable variables from environment variables */
   1824 void
   1825 _Py_Initialize_ReadEnvVarsNoAlloc(void)
   1826 {
   1827     _PyCmdline cmdline;
   1828     memset(&cmdline, 0, sizeof(cmdline));
   1829 
   1830     cmdline_get_global_config(&cmdline);
   1831     if (cmdline.isolated) {
   1832         Py_IgnoreEnvironmentFlag = 1;
   1833         cmdline.no_user_site_directory = 1;
   1834     }
   1835     if (!Py_IgnoreEnvironmentFlag) {
   1836         cmdline_get_env_flags(&cmdline);
   1837     }
   1838     cmdline_set_global_config(&cmdline);
   1839 
   1840     /* no need to call pymain_clear_cmdline(), no memory has been allocated */
   1841 }
   1842 
   1843 
   1844 static _PyInitError
   1845 config_init_home(_PyCoreConfig *config)
   1846 {
   1847     wchar_t *home;
   1848 
   1849     /* If Py_SetPythonHome() was called, use its value */
   1850     home = _Py_path_config.home;
   1851     if (home) {
   1852         config->home = _PyMem_RawWcsdup(home);
   1853         if (config->home == NULL) {
   1854             return _Py_INIT_NO_MEMORY();
   1855         }
   1856         return _Py_INIT_OK();
   1857     }
   1858 
   1859     int res = config_get_env_var_dup(&home, L"PYTHONHOME", "PYTHONHOME");
   1860     if (res < 0) {
   1861         return DECODE_LOCALE_ERR("PYTHONHOME", res);
   1862     }
   1863     config->home = home;
   1864     return _Py_INIT_OK();
   1865 }
   1866 
   1867 
   1868 static _PyInitError
   1869 config_init_hash_seed(_PyCoreConfig *config)
   1870 {
   1871     const char *seed_text = config_get_env_var("PYTHONHASHSEED");
   1872     int use_hash_seed;
   1873     unsigned long hash_seed;
   1874     if (_Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) {
   1875         return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" "
   1876                                  "or an integer in range [0; 4294967295]");
   1877     }
   1878     config->use_hash_seed = use_hash_seed;
   1879     config->hash_seed = hash_seed;
   1880     return _Py_INIT_OK();
   1881 }
   1882 
   1883 
   1884 static _PyInitError
   1885 config_init_utf8_mode(_PyCoreConfig *config)
   1886 {
   1887     const wchar_t *xopt = config_get_xoption(config, L"utf8");
   1888     if (xopt) {
   1889         wchar_t *sep = wcschr(xopt, L'=');
   1890         if (sep) {
   1891             xopt = sep + 1;
   1892             if (wcscmp(xopt, L"1") == 0) {
   1893                 config->utf8_mode = 1;
   1894             }
   1895             else if (wcscmp(xopt, L"0") == 0) {
   1896                 config->utf8_mode = 0;
   1897             }
   1898             else {
   1899                 return _Py_INIT_USER_ERR("invalid -X utf8 option value");
   1900             }
   1901         }
   1902         else {
   1903             config->utf8_mode = 1;
   1904         }
   1905         return _Py_INIT_OK();
   1906     }
   1907 
   1908     const char *opt = config_get_env_var("PYTHONUTF8");
   1909     if (opt) {
   1910         if (strcmp(opt, "1") == 0) {
   1911             config->utf8_mode = 1;
   1912         }
   1913         else if (strcmp(opt, "0") == 0) {
   1914             config->utf8_mode = 0;
   1915         }
   1916         else {
   1917             return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
   1918                                      "variable value");
   1919         }
   1920         return _Py_INIT_OK();
   1921     }
   1922 
   1923     return _Py_INIT_OK();
   1924 }
   1925 
   1926 
   1927 static _PyInitError
   1928 config_read_env_vars(_PyCoreConfig *config)
   1929 {
   1930     assert(!config->ignore_environment);
   1931 
   1932     if (config->allocator == NULL) {
   1933         config->allocator = config_get_env_var("PYTHONMALLOC");
   1934     }
   1935 
   1936     if (config_get_env_var("PYTHONDUMPREFS")) {
   1937         config->dump_refs = 1;
   1938     }
   1939     if (config_get_env_var("PYTHONMALLOCSTATS")) {
   1940         config->malloc_stats = 1;
   1941     }
   1942 
   1943     const char *env = config_get_env_var("PYTHONCOERCECLOCALE");
   1944     if (env) {
   1945         if (strcmp(env, "0") == 0) {
   1946             if (config->coerce_c_locale < 0) {
   1947                 config->coerce_c_locale = 0;
   1948             }
   1949         }
   1950         else if (strcmp(env, "warn") == 0) {
   1951             config->coerce_c_locale_warn = 1;
   1952         }
   1953         else {
   1954             if (config->coerce_c_locale < 0) {
   1955                 config->coerce_c_locale = 1;
   1956             }
   1957         }
   1958     }
   1959 
   1960     wchar_t *path;
   1961     int res = config_get_env_var_dup(&path, L"PYTHONPATH", "PYTHONPATH");
   1962     if (res < 0) {
   1963         return DECODE_LOCALE_ERR("PYTHONPATH", res);
   1964     }
   1965     config->module_search_path_env = path;
   1966 
   1967     if (config->use_hash_seed < 0) {
   1968         _PyInitError err = config_init_hash_seed(config);
   1969         if (_Py_INIT_FAILED(err)) {
   1970             return err;
   1971         }
   1972     }
   1973 
   1974     return _Py_INIT_OK();
   1975 }
   1976 
   1977 
   1978 static _PyInitError
   1979 config_read_complex_options(_PyCoreConfig *config)
   1980 {
   1981     /* More complex options configured by env var and -X option */
   1982     if (config->faulthandler < 0) {
   1983         if (config_get_env_var("PYTHONFAULTHANDLER")
   1984            || config_get_xoption(config, L"faulthandler")) {
   1985             config->faulthandler = 1;
   1986         }
   1987     }
   1988     if (config_get_env_var("PYTHONPROFILEIMPORTTIME")
   1989        || config_get_xoption(config, L"importtime")) {
   1990         config->import_time = 1;
   1991     }
   1992     if (config_get_xoption(config, L"dev" ) ||
   1993         config_get_env_var("PYTHONDEVMODE"))
   1994     {
   1995         config->dev_mode = 1;
   1996     }
   1997 
   1998     if (config->tracemalloc < 0) {
   1999         _PyInitError err = config_init_tracemalloc(config);
   2000         if (_Py_INIT_FAILED(err)) {
   2001             return err;
   2002         }
   2003     }
   2004     return _Py_INIT_OK();
   2005 }
   2006 
   2007 
   2008 /* Parse command line options and environment variables.
   2009    This code must not use Python runtime apart PyMem_Raw memory allocator.
   2010 
   2011    Return 0 on success.
   2012    Return 1 if Python is done and must exit.
   2013    Set pymain->err and return -1 on error. */
   2014 static int
   2015 pymain_read_conf_impl(_PyMain *pymain, _PyCoreConfig *config,
   2016                       _PyCmdline *cmdline)
   2017 {
   2018     _PyInitError err;
   2019 
   2020     int res = pymain_parse_cmdline(pymain, config, cmdline);
   2021     if (res != 0) {
   2022         return res;
   2023     }
   2024 
   2025     /* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */
   2026     Py_IgnoreEnvironmentFlag = config->ignore_environment || cmdline->isolated;
   2027 
   2028     /* Get environment variables */
   2029     if (!Py_IgnoreEnvironmentFlag) {
   2030         cmdline_get_env_flags(cmdline);
   2031     }
   2032 
   2033     err = cmdline_init_env_warnoptions(cmdline);
   2034     if (_Py_INIT_FAILED(err)) {
   2035         pymain->err = err;
   2036         return -1;
   2037     }
   2038 
   2039 #ifdef MS_WINDOWS
   2040     if (cmdline->legacy_windows_fs_encoding) {
   2041         config->utf8_mode = 0;
   2042     }
   2043 #endif
   2044 
   2045     if (pymain_init_core_argv(pymain, config, cmdline) < 0) {
   2046         return -1;
   2047     }
   2048 
   2049     /* On Windows, _PyPathConfig_Init() modifies Py_IsolatedFlag and
   2050        Py_NoSiteFlag variables if a "._pth" file is found. */
   2051     int init_isolated = Py_IsolatedFlag;
   2052     int init_no_site = Py_NoSiteFlag;
   2053     Py_IsolatedFlag = cmdline->isolated;
   2054     Py_NoSiteFlag = cmdline->no_site_import;
   2055 
   2056     err = _PyCoreConfig_Read(config);
   2057 
   2058     cmdline->isolated = Py_IsolatedFlag;
   2059     cmdline->no_site_import = Py_NoSiteFlag;
   2060     Py_IsolatedFlag = init_isolated;
   2061     Py_NoSiteFlag = init_no_site;
   2062 
   2063     if (_Py_INIT_FAILED(err)) {
   2064         pymain->err = err;
   2065         return -1;
   2066     }
   2067     return 0;
   2068 }
   2069 
   2070 
   2071 /* Read the configuration, but initialize also the LC_CTYPE locale:
   2072    enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
   2073 static int
   2074 pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
   2075 {
   2076     int init_utf8_mode = Py_UTF8Mode;
   2077     _PyCoreConfig save_config = _PyCoreConfig_INIT;
   2078     int res = -1;
   2079 
   2080     char *oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
   2081     if (oldloc == NULL) {
   2082         pymain->err = _Py_INIT_NO_MEMORY();
   2083         goto done;
   2084     }
   2085 
   2086     /* Reconfigure the locale to the default for this process */
   2087     _Py_SetLocaleFromEnv(LC_ALL);
   2088 
   2089     int locale_coerced = 0;
   2090     int loops = 0;
   2091     int init_ignore_env = config->ignore_environment;
   2092 
   2093     if (_PyCoreConfig_Copy(&save_config, config) < 0) {
   2094         pymain->err = _Py_INIT_NO_MEMORY();
   2095         goto done;
   2096     }
   2097 
   2098     while (1) {
   2099         int init_utf8_mode = config->utf8_mode;
   2100         int encoding_changed = 0;
   2101 
   2102         /* Watchdog to prevent an infinite loop */
   2103         loops++;
   2104         if (loops == 3) {
   2105             pymain->err = _Py_INIT_ERR("Encoding changed twice while "
   2106                                        "reading the configuration");
   2107             goto done;
   2108         }
   2109 
   2110         /* bpo-34207: Py_DecodeLocale(), Py_EncodeLocale() and similar
   2111            functions depend on Py_UTF8Mode. */
   2112         Py_UTF8Mode = config->utf8_mode;
   2113 
   2114         if (pymain_init_cmdline_argv(pymain, config, cmdline) < 0) {
   2115             goto done;
   2116         }
   2117 
   2118         int conf_res = pymain_read_conf_impl(pymain, config, cmdline);
   2119         if (conf_res != 0) {
   2120             res = conf_res;
   2121             goto done;
   2122         }
   2123 
   2124         /* The legacy C locale assumes ASCII as the default text encoding, which
   2125          * causes problems not only for the CPython runtime, but also other
   2126          * components like GNU readline.
   2127          *
   2128          * Accordingly, when the CLI detects it, it attempts to coerce it to a
   2129          * more capable UTF-8 based alternative.
   2130          *
   2131          * See the documentation of the PYTHONCOERCECLOCALE setting for more
   2132          * details.
   2133          */
   2134         if (config->coerce_c_locale && !locale_coerced) {
   2135             locale_coerced = 1;
   2136             _Py_CoerceLegacyLocale(config);
   2137             encoding_changed = 1;
   2138         }
   2139 
   2140         if (init_utf8_mode == -1) {
   2141             if (config->utf8_mode == 1) {
   2142                 /* UTF-8 Mode enabled */
   2143                 encoding_changed = 1;
   2144             }
   2145         }
   2146         else {
   2147             if (config->utf8_mode != init_utf8_mode) {
   2148                 encoding_changed = 1;
   2149             }
   2150         }
   2151 
   2152         if (!encoding_changed) {
   2153             break;
   2154         }
   2155 
   2156         /* Reset the configuration, except UTF-8 Mode. Set Py_UTF8Mode for
   2157            Py_DecodeLocale(). Reset Py_IgnoreEnvironmentFlag, modified by
   2158            pymain_read_conf_impl(). Reset Py_IsolatedFlag and Py_NoSiteFlag
   2159            modified by _PyCoreConfig_Read(). */
   2160         int new_utf8_mode = config->utf8_mode;
   2161         int new_coerce_c_locale = config->coerce_c_locale;
   2162         Py_IgnoreEnvironmentFlag = init_ignore_env;
   2163         if (_PyCoreConfig_Copy(config, &save_config) < 0) {
   2164             pymain->err = _Py_INIT_NO_MEMORY();
   2165             goto done;
   2166         }
   2167         pymain_clear_cmdline(pymain, cmdline);
   2168         pymain_clear_pymain(pymain);
   2169         memset(cmdline, 0, sizeof(*cmdline));
   2170 
   2171         cmdline_get_global_config(cmdline);
   2172         _PyCoreConfig_GetGlobalConfig(config);
   2173         config->utf8_mode = new_utf8_mode;
   2174         config->coerce_c_locale = new_coerce_c_locale;
   2175 
   2176         /* The encoding changed: read again the configuration
   2177            with the new encoding */
   2178     }
   2179     res = 0;
   2180 
   2181 done:
   2182     _PyCoreConfig_Clear(&save_config);
   2183     if (oldloc != NULL) {
   2184         setlocale(LC_ALL, oldloc);
   2185         PyMem_RawFree(oldloc);
   2186     }
   2187     Py_UTF8Mode = init_utf8_mode ;
   2188     return res;
   2189 }
   2190 
   2191 
   2192 static void
   2193 config_init_locale(_PyCoreConfig *config)
   2194 {
   2195     /* Test also if coerce_c_locale equals 1: PYTHONCOERCECLOCALE=1 doesn't
   2196        imply that the C locale is always coerced. It is only coerced if
   2197        if the LC_CTYPE locale is "C". */
   2198     if (config->coerce_c_locale != 0) {
   2199         /* The C locale enables the C locale coercion (PEP 538) */
   2200         if (_Py_LegacyLocaleDetected()) {
   2201             config->coerce_c_locale = 1;
   2202         }
   2203         else {
   2204             config->coerce_c_locale = 0;
   2205         }
   2206     }
   2207 
   2208 #ifndef MS_WINDOWS
   2209     if (config->utf8_mode < 0) {
   2210         /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
   2211         const char *ctype_loc = setlocale(LC_CTYPE, NULL);
   2212         if (ctype_loc != NULL
   2213            && (strcmp(ctype_loc, "C") == 0
   2214                || strcmp(ctype_loc, "POSIX") == 0))
   2215         {
   2216             config->utf8_mode = 1;
   2217         }
   2218     }
   2219 #endif
   2220 }
   2221 
   2222 
   2223 static _PyInitError
   2224 config_init_module_search_paths(_PyCoreConfig *config)
   2225 {
   2226     assert(config->module_search_paths == NULL);
   2227     assert(config->nmodule_search_path < 0);
   2228 
   2229     config->nmodule_search_path = 0;
   2230 
   2231     const wchar_t *sys_path = Py_GetPath();
   2232     const wchar_t delim = DELIM;
   2233     const wchar_t *p = sys_path;
   2234     while (1) {
   2235         p = wcschr(sys_path, delim);
   2236         if (p == NULL) {
   2237             p = sys_path + wcslen(sys_path); /* End of string */
   2238         }
   2239 
   2240         size_t path_len = (p - sys_path);
   2241         wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t));
   2242         if (path == NULL) {
   2243             return _Py_INIT_NO_MEMORY();
   2244         }
   2245         memcpy(path, sys_path, path_len * sizeof(wchar_t));
   2246         path[path_len] = L'\0';
   2247 
   2248         _PyInitError err = wstrlist_append(&config->nmodule_search_path,
   2249                                            &config->module_search_paths,
   2250                                            path);
   2251         PyMem_RawFree(path);
   2252         if (_Py_INIT_FAILED(err)) {
   2253             return err;
   2254         }
   2255 
   2256         if (*p == '\0') {
   2257             break;
   2258         }
   2259         sys_path = p + 1;
   2260     }
   2261     return _Py_INIT_OK();
   2262 }
   2263 
   2264 
   2265 static _PyInitError
   2266 config_init_path_config(_PyCoreConfig *config)
   2267 {
   2268     _PyInitError err = _PyPathConfig_Init(config);
   2269     if (_Py_INIT_FAILED(err)) {
   2270         return err;
   2271     }
   2272 
   2273     if (config->nmodule_search_path < 0) {
   2274         err = config_init_module_search_paths(config);
   2275         if (_Py_INIT_FAILED(err)) {
   2276             return err;
   2277         }
   2278     }
   2279 
   2280     if (config->executable == NULL) {
   2281         config->executable = _PyMem_RawWcsdup(Py_GetProgramFullPath());
   2282         if (config->executable == NULL) {
   2283             return _Py_INIT_NO_MEMORY();
   2284         }
   2285     }
   2286 
   2287     if (config->prefix == NULL) {
   2288         config->prefix = _PyMem_RawWcsdup(Py_GetPrefix());
   2289         if (config->prefix == NULL) {
   2290             return _Py_INIT_NO_MEMORY();
   2291         }
   2292     }
   2293 
   2294     if (config->exec_prefix == NULL) {
   2295         config->exec_prefix = _PyMem_RawWcsdup(Py_GetExecPrefix());
   2296         if (config->exec_prefix == NULL) {
   2297             return _Py_INIT_NO_MEMORY();
   2298         }
   2299     }
   2300 
   2301     if (config->base_prefix == NULL) {
   2302         config->base_prefix = _PyMem_RawWcsdup(config->prefix);
   2303         if (config->base_prefix == NULL) {
   2304             return _Py_INIT_NO_MEMORY();
   2305         }
   2306     }
   2307 
   2308     if (config->base_exec_prefix == NULL) {
   2309         config->base_exec_prefix = _PyMem_RawWcsdup(config->exec_prefix);
   2310         if (config->base_exec_prefix == NULL) {
   2311             return _Py_INIT_NO_MEMORY();
   2312         }
   2313     }
   2314 
   2315     return _Py_INIT_OK();
   2316 }
   2317 
   2318 /* Read configuration settings from standard locations
   2319  *
   2320  * This function doesn't make any changes to the interpreter state - it
   2321  * merely populates any missing configuration settings. This allows an
   2322  * embedding application to completely override a config option by
   2323  * setting it before calling this function, or else modify the default
   2324  * setting before passing the fully populated config to Py_EndInitialization.
   2325  *
   2326  * More advanced selective initialization tricks are possible by calling
   2327  * this function multiple times with various preconfigured settings.
   2328  */
   2329 
   2330 _PyInitError
   2331 _PyCoreConfig_Read(_PyCoreConfig *config)
   2332 {
   2333     _PyInitError err;
   2334 
   2335     _PyCoreConfig_GetGlobalConfig(config);
   2336 
   2337     assert(config->ignore_environment >= 0);
   2338     if (!config->ignore_environment) {
   2339         err = config_read_env_vars(config);
   2340         if (_Py_INIT_FAILED(err)) {
   2341             return err;
   2342         }
   2343     }
   2344 
   2345     /* -X options */
   2346     if (config_get_xoption(config, L"showrefcount")) {
   2347         config->show_ref_count = 1;
   2348     }
   2349     if (config_get_xoption(config, L"showalloccount")) {
   2350         config->show_alloc_count = 1;
   2351     }
   2352 
   2353     err = config_read_complex_options(config);
   2354     if (_Py_INIT_FAILED(err)) {
   2355         return err;
   2356     }
   2357 
   2358     if (config->utf8_mode < 0) {
   2359         err = config_init_utf8_mode(config);
   2360         if (_Py_INIT_FAILED(err)) {
   2361             return err;
   2362         }
   2363     }
   2364 
   2365     if (config->home == NULL) {
   2366         err = config_init_home(config);
   2367         if (_Py_INIT_FAILED(err)) {
   2368             return err;
   2369         }
   2370     }
   2371 
   2372     if (config->program_name == NULL) {
   2373         err = config_init_program_name(config);
   2374         if (_Py_INIT_FAILED(err)) {
   2375             return err;
   2376         }
   2377     }
   2378 
   2379     if (config->executable == NULL) {
   2380         err = config_init_executable(config);
   2381         if (_Py_INIT_FAILED(err)) {
   2382             return err;
   2383         }
   2384     }
   2385 
   2386     if (config->coerce_c_locale != 0 || config->utf8_mode < 0) {
   2387         config_init_locale(config);
   2388     }
   2389 
   2390     if (!config->_disable_importlib) {
   2391         err = config_init_path_config(config);
   2392         if (_Py_INIT_FAILED(err)) {
   2393             return err;
   2394         }
   2395     }
   2396 
   2397     /* default values */
   2398     if (config->dev_mode) {
   2399         if (config->faulthandler < 0) {
   2400             config->faulthandler = 1;
   2401         }
   2402         if (config->allocator == NULL) {
   2403             config->allocator = "debug";
   2404         }
   2405     }
   2406     if (config->install_signal_handlers < 0) {
   2407         config->install_signal_handlers = 1;
   2408     }
   2409     if (config->use_hash_seed < 0) {
   2410         config->use_hash_seed = 0;
   2411         config->hash_seed = 0;
   2412     }
   2413     if (config->faulthandler < 0) {
   2414         config->faulthandler = 0;
   2415     }
   2416     if (config->tracemalloc < 0) {
   2417         config->tracemalloc = 0;
   2418     }
   2419     if (config->coerce_c_locale < 0) {
   2420         config->coerce_c_locale = 0;
   2421     }
   2422     if (config->utf8_mode < 0) {
   2423         config->utf8_mode = 0;
   2424     }
   2425     if (config->argc < 0) {
   2426         config->argc = 0;
   2427     }
   2428 
   2429     return _Py_INIT_OK();
   2430 }
   2431 
   2432 
   2433 void
   2434 _PyCoreConfig_Clear(_PyCoreConfig *config)
   2435 {
   2436 #define CLEAR(ATTR) \
   2437     do { \
   2438         PyMem_RawFree(ATTR); \
   2439         ATTR = NULL; \
   2440     } while (0)
   2441 #define CLEAR_WSTRLIST(LEN, LIST) \
   2442     do { \
   2443         clear_wstrlist(LEN, LIST); \
   2444         LEN = 0; \
   2445         LIST = NULL; \
   2446     } while (0)
   2447 
   2448     CLEAR(config->module_search_path_env);
   2449     CLEAR(config->home);
   2450     CLEAR(config->program_name);
   2451     CLEAR(config->program);
   2452 
   2453     CLEAR_WSTRLIST(config->argc, config->argv);
   2454     config->argc = -1;
   2455 
   2456     CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions);
   2457     CLEAR_WSTRLIST(config->nxoption, config->xoptions);
   2458     CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths);
   2459     config->nmodule_search_path = -1;
   2460 
   2461     CLEAR(config->executable);
   2462     CLEAR(config->prefix);
   2463     CLEAR(config->base_prefix);
   2464     CLEAR(config->exec_prefix);
   2465     CLEAR(config->base_exec_prefix);
   2466 #undef CLEAR
   2467 #undef CLEAR_WSTRLIST
   2468 }
   2469 
   2470 
   2471 int
   2472 _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
   2473 {
   2474     _PyCoreConfig_Clear(config);
   2475 
   2476 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
   2477 #define COPY_STR_ATTR(ATTR) \
   2478     do { \
   2479         if (config2->ATTR != NULL) { \
   2480             config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
   2481             if (config->ATTR == NULL) { \
   2482                 return -1; \
   2483             } \
   2484         } \
   2485     } while (0)
   2486 #define COPY_WSTRLIST(LEN, LIST) \
   2487     do { \
   2488         if (config2->LIST != NULL) { \
   2489             config->LIST = copy_wstrlist(config2->LEN, config2->LIST); \
   2490             if (config->LIST == NULL) { \
   2491                 return -1; \
   2492             } \
   2493         } \
   2494         config->LEN = config2->LEN; \
   2495     } while (0)
   2496 
   2497     COPY_ATTR(install_signal_handlers);
   2498     COPY_ATTR(ignore_environment);
   2499     COPY_ATTR(use_hash_seed);
   2500     COPY_ATTR(hash_seed);
   2501     COPY_ATTR(_disable_importlib);
   2502     COPY_ATTR(allocator);
   2503     COPY_ATTR(dev_mode);
   2504     COPY_ATTR(faulthandler);
   2505     COPY_ATTR(tracemalloc);
   2506     COPY_ATTR(import_time);
   2507     COPY_ATTR(show_ref_count);
   2508     COPY_ATTR(show_alloc_count);
   2509     COPY_ATTR(dump_refs);
   2510     COPY_ATTR(malloc_stats);
   2511 
   2512     COPY_ATTR(coerce_c_locale);
   2513     COPY_ATTR(coerce_c_locale_warn);
   2514     COPY_ATTR(utf8_mode);
   2515 
   2516     COPY_STR_ATTR(module_search_path_env);
   2517     COPY_STR_ATTR(home);
   2518     COPY_STR_ATTR(program_name);
   2519     COPY_STR_ATTR(program);
   2520 
   2521     COPY_WSTRLIST(argc, argv);
   2522     COPY_WSTRLIST(nwarnoption, warnoptions);
   2523     COPY_WSTRLIST(nxoption, xoptions);
   2524     COPY_WSTRLIST(nmodule_search_path, module_search_paths);
   2525 
   2526     COPY_STR_ATTR(executable);
   2527     COPY_STR_ATTR(prefix);
   2528     COPY_STR_ATTR(base_prefix);
   2529     COPY_STR_ATTR(exec_prefix);
   2530     COPY_STR_ATTR(base_exec_prefix);
   2531 
   2532 #undef COPY_ATTR
   2533 #undef COPY_STR_ATTR
   2534 #undef COPY_WSTRLIST
   2535     return 0;
   2536 }
   2537 
   2538 
   2539 PyObject *
   2540 _PyCoreConfig_AsDict(const _PyCoreConfig *config)
   2541 {
   2542     PyObject *dict, *obj;
   2543 
   2544     dict = PyDict_New();
   2545     if (dict == NULL) {
   2546         return NULL;
   2547     }
   2548 
   2549 #define SET_ITEM(KEY, EXPR) \
   2550         do { \
   2551             obj = (EXPR); \
   2552             if (obj == NULL) { \
   2553                 return NULL; \
   2554             } \
   2555             int res = PyDict_SetItemString(dict, (KEY), obj); \
   2556             Py_DECREF(obj); \
   2557             if (res < 0) { \
   2558                 goto fail; \
   2559             } \
   2560         } while (0)
   2561 #define FROM_STRING(STR) \
   2562     ((STR != NULL) ? \
   2563         PyUnicode_FromString(STR) \
   2564         : (Py_INCREF(Py_None), Py_None))
   2565 #define SET_ITEM_INT(ATTR) \
   2566     SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
   2567 #define SET_ITEM_UINT(ATTR) \
   2568     SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
   2569 #define SET_ITEM_STR(ATTR) \
   2570     SET_ITEM(#ATTR, FROM_STRING(config->ATTR))
   2571 #define FROM_WSTRING(STR) \
   2572     ((STR != NULL) ? \
   2573         PyUnicode_FromWideChar(STR, -1) \
   2574         : (Py_INCREF(Py_None), Py_None))
   2575 #define SET_ITEM_WSTR(ATTR) \
   2576     SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
   2577 #define SET_ITEM_WSTRLIST(NOPTION, OPTIONS) \
   2578     SET_ITEM(#OPTIONS, _Py_wstrlist_as_pylist(config->NOPTION, config->OPTIONS))
   2579 
   2580     SET_ITEM_INT(install_signal_handlers);
   2581     SET_ITEM_INT(ignore_environment);
   2582     SET_ITEM_INT(use_hash_seed);
   2583     SET_ITEM_UINT(hash_seed);
   2584     SET_ITEM_STR(allocator);
   2585     SET_ITEM_INT(dev_mode);
   2586     SET_ITEM_INT(faulthandler);
   2587     SET_ITEM_INT(tracemalloc);
   2588     SET_ITEM_INT(import_time);
   2589     SET_ITEM_INT(show_ref_count);
   2590     SET_ITEM_INT(show_alloc_count);
   2591     SET_ITEM_INT(dump_refs);
   2592     SET_ITEM_INT(malloc_stats);
   2593     SET_ITEM_INT(coerce_c_locale);
   2594     SET_ITEM_INT(coerce_c_locale_warn);
   2595     SET_ITEM_INT(utf8_mode);
   2596     SET_ITEM_WSTR(program_name);
   2597     SET_ITEM_WSTRLIST(argc, argv);
   2598     SET_ITEM_WSTR(program);
   2599     SET_ITEM_WSTRLIST(nxoption, xoptions);
   2600     SET_ITEM_WSTRLIST(nwarnoption, warnoptions);
   2601     SET_ITEM_WSTR(module_search_path_env);
   2602     SET_ITEM_WSTR(home);
   2603     SET_ITEM_WSTRLIST(nmodule_search_path, module_search_paths);
   2604     SET_ITEM_WSTR(executable);
   2605     SET_ITEM_WSTR(prefix);
   2606     SET_ITEM_WSTR(base_prefix);
   2607     SET_ITEM_WSTR(exec_prefix);
   2608     SET_ITEM_WSTR(base_exec_prefix);
   2609     SET_ITEM_INT(_disable_importlib);
   2610 
   2611     return dict;
   2612 
   2613 fail:
   2614     Py_DECREF(dict);
   2615     return NULL;
   2616 
   2617 #undef FROM_STRING
   2618 #undef FROM_WSTRING
   2619 #undef SET_ITEM
   2620 #undef SET_ITEM_INT
   2621 #undef SET_ITEM_UINT
   2622 #undef SET_ITEM_STR
   2623 #undef SET_ITEM_WSTR
   2624 #undef SET_ITEM_WSTRLIST
   2625 }
   2626 
   2627 
   2628 void
   2629 _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
   2630 {
   2631     Py_CLEAR(config->argv);
   2632     Py_CLEAR(config->executable);
   2633     Py_CLEAR(config->prefix);
   2634     Py_CLEAR(config->base_prefix);
   2635     Py_CLEAR(config->exec_prefix);
   2636     Py_CLEAR(config->base_exec_prefix);
   2637     Py_CLEAR(config->warnoptions);
   2638     Py_CLEAR(config->xoptions);
   2639     Py_CLEAR(config->module_search_path);
   2640 }
   2641 
   2642 
   2643 static PyObject*
   2644 config_copy_attr(PyObject *obj)
   2645 {
   2646     if (PyUnicode_Check(obj)) {
   2647         Py_INCREF(obj);
   2648         return obj;
   2649     }
   2650     else if (PyList_Check(obj)) {
   2651         return PyList_GetSlice(obj, 0, Py_SIZE(obj));
   2652     }
   2653     else if (PyDict_Check(obj)) {
   2654         /* The dict type is used for xoptions. Make the assumption that keys
   2655            and values are immutables */
   2656         return PyDict_Copy(obj);
   2657     }
   2658     else {
   2659         PyErr_Format(PyExc_TypeError,
   2660                      "cannot copy config attribute of type %.200s",
   2661                      Py_TYPE(obj)->tp_name);
   2662         return NULL;
   2663     }
   2664 }
   2665 
   2666 
   2667 int
   2668 _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,
   2669                               const _PyMainInterpreterConfig *config2)
   2670 {
   2671     _PyMainInterpreterConfig_Clear(config);
   2672 
   2673 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
   2674 #define COPY_OBJ_ATTR(ATTR) \
   2675     do { \
   2676         if (config2->ATTR != NULL) { \
   2677             config->ATTR = config_copy_attr(config2->ATTR); \
   2678             if (config->ATTR == NULL) { \
   2679                 return -1; \
   2680             } \
   2681         } \
   2682     } while (0)
   2683 
   2684     COPY_ATTR(install_signal_handlers);
   2685     COPY_OBJ_ATTR(argv);
   2686     COPY_OBJ_ATTR(executable);
   2687     COPY_OBJ_ATTR(prefix);
   2688     COPY_OBJ_ATTR(base_prefix);
   2689     COPY_OBJ_ATTR(exec_prefix);
   2690     COPY_OBJ_ATTR(base_exec_prefix);
   2691     COPY_OBJ_ATTR(warnoptions);
   2692     COPY_OBJ_ATTR(xoptions);
   2693     COPY_OBJ_ATTR(module_search_path);
   2694 #undef COPY_ATTR
   2695 #undef COPY_OBJ_ATTR
   2696     return 0;
   2697 }
   2698 
   2699 
   2700 PyObject*
   2701 _PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config)
   2702 {
   2703     PyObject *dict, *obj;
   2704     int res;
   2705 
   2706     dict = PyDict_New();
   2707     if (dict == NULL) {
   2708         return NULL;
   2709     }
   2710 
   2711 #define SET_ITEM_INT(ATTR) \
   2712     do { \
   2713         obj = PyLong_FromLong(config->ATTR); \
   2714         if (obj == NULL) { \
   2715             goto fail; \
   2716         } \
   2717         res = PyDict_SetItemString(dict, #ATTR, obj); \
   2718         Py_DECREF(obj); \
   2719         if (res < 0) { \
   2720             goto fail; \
   2721         } \
   2722     } while (0)
   2723 
   2724 #define SET_ITEM_OBJ(ATTR) \
   2725     do { \
   2726         obj = config->ATTR; \
   2727         if (obj == NULL) { \
   2728             obj = Py_None; \
   2729         } \
   2730         res = PyDict_SetItemString(dict, #ATTR, obj); \
   2731         if (res < 0) { \
   2732             goto fail; \
   2733         } \
   2734     } while (0)
   2735 
   2736     SET_ITEM_INT(install_signal_handlers);
   2737     SET_ITEM_OBJ(argv);
   2738     SET_ITEM_OBJ(executable);
   2739     SET_ITEM_OBJ(prefix);
   2740     SET_ITEM_OBJ(base_prefix);
   2741     SET_ITEM_OBJ(exec_prefix);
   2742     SET_ITEM_OBJ(base_exec_prefix);
   2743     SET_ITEM_OBJ(warnoptions);
   2744     SET_ITEM_OBJ(xoptions);
   2745     SET_ITEM_OBJ(module_search_path);
   2746 
   2747     return dict;
   2748 
   2749 fail:
   2750     Py_DECREF(dict);
   2751     return NULL;
   2752 
   2753 #undef SET_ITEM_OBJ
   2754 }
   2755 
   2756 
   2757 _PyInitError
   2758 _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
   2759                               const _PyCoreConfig *config)
   2760 {
   2761     if (main_config->install_signal_handlers < 0) {
   2762         main_config->install_signal_handlers = config->install_signal_handlers;
   2763     }
   2764 
   2765     if (main_config->xoptions == NULL) {
   2766         main_config->xoptions = config_create_xoptions_dict(config);
   2767         if (main_config->xoptions == NULL) {
   2768             return _Py_INIT_NO_MEMORY();
   2769         }
   2770     }
   2771 
   2772 #define COPY_WSTR(ATTR) \
   2773     do { \
   2774         if (main_config->ATTR == NULL) { \
   2775             main_config->ATTR = PyUnicode_FromWideChar(config->ATTR, -1); \
   2776             if (main_config->ATTR == NULL) { \
   2777                 return _Py_INIT_NO_MEMORY(); \
   2778             } \
   2779         } \
   2780     } while (0)
   2781 #define COPY_WSTRLIST(ATTR, LEN, LIST) \
   2782     do { \
   2783         if (ATTR == NULL) { \
   2784             ATTR = _Py_wstrlist_as_pylist(LEN, LIST); \
   2785             if (ATTR == NULL) { \
   2786                 return _Py_INIT_NO_MEMORY(); \
   2787             } \
   2788         } \
   2789     } while (0)
   2790 
   2791     COPY_WSTRLIST(main_config->warnoptions,
   2792                   config->nwarnoption, config->warnoptions);
   2793     if (config->argc >= 0) {
   2794         COPY_WSTRLIST(main_config->argv,
   2795                       config->argc, config->argv);
   2796     }
   2797 
   2798     if (!config->_disable_importlib) {
   2799         COPY_WSTR(executable);
   2800         COPY_WSTR(prefix);
   2801         COPY_WSTR(base_prefix);
   2802         COPY_WSTR(exec_prefix);
   2803         COPY_WSTR(base_exec_prefix);
   2804 
   2805         COPY_WSTRLIST(main_config->module_search_path,
   2806                       config->nmodule_search_path, config->module_search_paths);
   2807     }
   2808 
   2809     return _Py_INIT_OK();
   2810 #undef COPY_WSTR
   2811 #undef COPY_WSTRLIST
   2812 }
   2813 
   2814 
   2815 static int
   2816 pymain_init_python_main(_PyMain *pymain, PyInterpreterState *interp)
   2817 {
   2818     _PyInitError err;
   2819 
   2820     _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
   2821     err = _PyMainInterpreterConfig_Read(&main_config, &interp->core_config);
   2822     if (!_Py_INIT_FAILED(err)) {
   2823         err = _Py_InitializeMainInterpreter(interp, &main_config);
   2824     }
   2825     _PyMainInterpreterConfig_Clear(&main_config);
   2826 
   2827     if (_Py_INIT_FAILED(err)) {
   2828         pymain->err = err;
   2829         return -1;
   2830     }
   2831     return 0;
   2832 }
   2833 
   2834 
   2835 static int
   2836 pymain_init_sys_path(_PyMain *pymain, _PyCoreConfig *config)
   2837 {
   2838     if (pymain->filename != NULL) {
   2839         /* If filename is a package (ex: directory or ZIP file) which contains
   2840            __main__.py, main_importer_path is set to filename and will be
   2841            prepended to sys.path by pymain_run_main_from_importer(). Otherwise,
   2842            main_importer_path is set to NULL. */
   2843         pymain->main_importer_path = pymain_get_importer(pymain->filename);
   2844     }
   2845 
   2846     PyObject *path0;
   2847     if (pymain_compute_path0(pymain, config, &path0) < 0) {
   2848         return -1;
   2849     }
   2850 
   2851     if (path0 != NULL) {
   2852         if (pymain_update_sys_path(pymain, path0) < 0) {
   2853             Py_DECREF(path0);
   2854             return -1;
   2855         }
   2856         Py_DECREF(path0);
   2857     }
   2858     return 0;
   2859 }
   2860 
   2861 
   2862 static void
   2863 pymain_run_python(_PyMain *pymain)
   2864 {
   2865     PyCompilerFlags cf = {.cf_flags = 0};
   2866 
   2867     pymain_header(pymain);
   2868     pymain_import_readline(pymain);
   2869 
   2870     if (pymain->command) {
   2871         pymain->status = pymain_run_command(pymain->command, &cf);
   2872     }
   2873     else if (pymain->module) {
   2874         pymain->status = (pymain_run_module(pymain->module, 1) != 0);
   2875     }
   2876     else {
   2877         pymain_run_filename(pymain, &cf);
   2878     }
   2879 
   2880     pymain_repl(pymain, &cf);
   2881 }
   2882 
   2883 
   2884 static int
   2885 pymain_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
   2886                     _PyCmdline *cmdline)
   2887 {
   2888     pymain->err = _PyRuntime_Initialize();
   2889     if (_Py_INIT_FAILED(pymain->err)) {
   2890         return -1;
   2891     }
   2892 
   2893     int res = pymain_read_conf(pymain, config, cmdline);
   2894     if (res < 0) {
   2895         return -1;
   2896     }
   2897     if (res > 0) {
   2898         /* --help or --version command: we are done */
   2899         return 1;
   2900     }
   2901 
   2902     if (cmdline->print_help) {
   2903         pymain_usage(0, config->program);
   2904         return 1;
   2905     }
   2906 
   2907     if (cmdline->print_version) {
   2908         printf("Python %s\n",
   2909                (cmdline->print_version >= 2) ? Py_GetVersion() : PY_VERSION);
   2910         return 1;
   2911     }
   2912 
   2913     /* For Py_GetArgcArgv(). Cleared by pymain_free(). */
   2914     orig_argv = copy_wstrlist(pymain->argc, cmdline->argv);
   2915     if (orig_argv == NULL) {
   2916         pymain->err = _Py_INIT_NO_MEMORY();
   2917         return -1;
   2918     }
   2919     orig_argc = pymain->argc;
   2920 
   2921     _PyInitError err = config_init_warnoptions(config, cmdline);
   2922     if (_Py_INIT_FAILED(err)) {
   2923         pymain->err = err;
   2924         return -1;
   2925     }
   2926     return 0;
   2927 }
   2928 
   2929 
   2930 /* Read the configuration into _PyCoreConfig and _PyMain, initialize the
   2931    LC_CTYPE locale and Py_DecodeLocale().
   2932 
   2933    Configuration:
   2934 
   2935    * Command line arguments
   2936    * Environment variables
   2937    * Py_xxx global configuration variables
   2938 
   2939    _PyCmdline is a temporary structure used to prioritize these
   2940    variables. */
   2941 static int
   2942 pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
   2943 {
   2944     /* Force default allocator, since pymain_free() and pymain_clear_config()
   2945        must use the same allocator than this function. */
   2946     PyMemAllocatorEx old_alloc;
   2947     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
   2948 #ifdef Py_DEBUG
   2949     PyMemAllocatorEx default_alloc;
   2950     PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &default_alloc);
   2951 #endif
   2952 
   2953     _PyCmdline cmdline;
   2954     memset(&cmdline, 0, sizeof(cmdline));
   2955 
   2956     cmdline_get_global_config(&cmdline);
   2957 
   2958     int res = pymain_cmdline_impl(pymain, config, &cmdline);
   2959 
   2960     cmdline_set_global_config(&cmdline);
   2961     _PyCoreConfig_SetGlobalConfig(config);
   2962     if (Py_IsolatedFlag) {
   2963         Py_IgnoreEnvironmentFlag = 1;
   2964         Py_NoUserSiteDirectory = 1;
   2965     }
   2966 
   2967     pymain_clear_cmdline(pymain, &cmdline);
   2968 
   2969 #ifdef Py_DEBUG
   2970     /* Make sure that PYMEM_DOMAIN_RAW has not been modified */
   2971     PyMemAllocatorEx cur_alloc;
   2972     PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &cur_alloc);
   2973     assert(memcmp(&cur_alloc, &default_alloc, sizeof(cur_alloc)) == 0);
   2974 #endif
   2975     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
   2976     return res;
   2977 }
   2978 
   2979 
   2980 static int
   2981 pymain_init(_PyMain *pymain)
   2982 {
   2983     _PyCoreConfig local_config = _PyCoreConfig_INIT;
   2984     _PyCoreConfig *config = &local_config;
   2985 
   2986     /* 754 requires that FP exceptions run in "no stop" mode by default,
   2987      * and until C vendors implement C99's ways to control FP exceptions,
   2988      * Python requires non-stop mode.  Alas, some platforms enable FP
   2989      * exceptions by default.  Here we disable them.
   2990      */
   2991 #ifdef __FreeBSD__
   2992     fedisableexcept(FE_OVERFLOW);
   2993 #endif
   2994 
   2995     config->_disable_importlib = 0;
   2996     config->install_signal_handlers = 1;
   2997     _PyCoreConfig_GetGlobalConfig(config);
   2998 
   2999     int res = pymain_cmdline(pymain, config);
   3000     if (res < 0) {
   3001         _Py_FatalInitError(pymain->err);
   3002     }
   3003     if (res == 1) {
   3004         pymain_clear_config(&local_config);
   3005         return res;
   3006     }
   3007 
   3008     pymain_init_stdio(pymain);
   3009 
   3010     PyInterpreterState *interp;
   3011     pymain->err = _Py_InitializeCore(&interp, config);
   3012     if (_Py_INIT_FAILED(pymain->err)) {
   3013         _Py_FatalInitError(pymain->err);
   3014     }
   3015 
   3016     pymain_clear_config(&local_config);
   3017     config = &interp->core_config;
   3018 
   3019     if (pymain_init_python_main(pymain, interp) < 0) {
   3020         _Py_FatalInitError(pymain->err);
   3021     }
   3022 
   3023     if (pymain_init_sys_path(pymain, config) < 0) {
   3024         _Py_FatalInitError(pymain->err);
   3025     }
   3026     return 0;
   3027 }
   3028 
   3029 
   3030 static int
   3031 pymain_main(_PyMain *pymain)
   3032 {
   3033     int res = pymain_init(pymain);
   3034     if (res == 1) {
   3035         goto done;
   3036     }
   3037 
   3038     pymain_run_python(pymain);
   3039 
   3040     if (Py_FinalizeEx() < 0) {
   3041         /* Value unlikely to be confused with a non-error exit status or
   3042            other special meaning */
   3043         pymain->status = 120;
   3044     }
   3045 
   3046 done:
   3047     pymain_free(pymain);
   3048 
   3049     return pymain->status;
   3050 }
   3051 
   3052 
   3053 int
   3054 Py_Main(int argc, wchar_t **argv)
   3055 {
   3056     _PyMain pymain = _PyMain_INIT;
   3057     pymain.use_bytes_argv = 0;
   3058     pymain.argc = argc;
   3059     pymain.wchar_argv = argv;
   3060 
   3061     return pymain_main(&pymain);
   3062 }
   3063 
   3064 
   3065 int
   3066 _Py_UnixMain(int argc, char **argv)
   3067 {
   3068     _PyMain pymain = _PyMain_INIT;
   3069     pymain.use_bytes_argv = 1;
   3070     pymain.argc = argc;
   3071     pymain.bytes_argv = argv;
   3072 
   3073     return pymain_main(&pymain);
   3074 }
   3075 
   3076 
   3077 /* this is gonna seem *real weird*, but if you put some other code between
   3078    Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
   3079    while statement in Misc/gdbinit:ppystack */
   3080 
   3081 /* Make the *original* argc/argv available to other modules.
   3082    This is rare, but it is needed by the secureware extension. */
   3083 
   3084 void
   3085 Py_GetArgcArgv(int *argc, wchar_t ***argv)
   3086 {
   3087     *argc = orig_argc;
   3088     *argv = orig_argv;
   3089 }
   3090 
   3091 #ifdef __cplusplus
   3092 }
   3093 #endif
   3094