17db96d56Sopenharmony_ci/* Python interpreter main program */
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci#include "Python.h"
47db96d56Sopenharmony_ci#include "pycore_call.h"          // _PyObject_CallNoArgs()
57db96d56Sopenharmony_ci#include "pycore_initconfig.h"    // _PyArgv
67db96d56Sopenharmony_ci#include "pycore_interp.h"        // _PyInterpreterState.sysdict
77db96d56Sopenharmony_ci#include "pycore_pathconfig.h"    // _PyPathConfig_ComputeSysPath0()
87db96d56Sopenharmony_ci#include "pycore_pylifecycle.h"   // _Py_PreInitializeFromPyArgv()
97db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyInterpreterState_GET()
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci/* Includes for exit_sigint() */
127db96d56Sopenharmony_ci#include <stdio.h>                // perror()
137db96d56Sopenharmony_ci#ifdef HAVE_SIGNAL_H
147db96d56Sopenharmony_ci#  include <signal.h>             // SIGINT
157db96d56Sopenharmony_ci#endif
167db96d56Sopenharmony_ci#if defined(HAVE_GETPID) && defined(HAVE_UNISTD_H)
177db96d56Sopenharmony_ci#  include <unistd.h>             // getpid()
187db96d56Sopenharmony_ci#endif
197db96d56Sopenharmony_ci#ifdef MS_WINDOWS
207db96d56Sopenharmony_ci#  include <windows.h>            // STATUS_CONTROL_C_EXIT
217db96d56Sopenharmony_ci#endif
227db96d56Sopenharmony_ci/* End of includes for exit_sigint() */
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci#define COPYRIGHT \
257db96d56Sopenharmony_ci    "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
267db96d56Sopenharmony_ci    "for more information."
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci#ifdef __cplusplus
297db96d56Sopenharmony_ciextern "C" {
307db96d56Sopenharmony_ci#endif
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci/* --- pymain_init() ---------------------------------------------- */
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_cistatic PyStatus
357db96d56Sopenharmony_cipymain_init(const _PyArgv *args)
367db96d56Sopenharmony_ci{
377db96d56Sopenharmony_ci    PyStatus status;
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci    status = _PyRuntime_Initialize();
407db96d56Sopenharmony_ci    if (_PyStatus_EXCEPTION(status)) {
417db96d56Sopenharmony_ci        return status;
427db96d56Sopenharmony_ci    }
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci    PyPreConfig preconfig;
457db96d56Sopenharmony_ci    PyPreConfig_InitPythonConfig(&preconfig);
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci    status = _Py_PreInitializeFromPyArgv(&preconfig, args);
487db96d56Sopenharmony_ci    if (_PyStatus_EXCEPTION(status)) {
497db96d56Sopenharmony_ci        return status;
507db96d56Sopenharmony_ci    }
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci    PyConfig config;
537db96d56Sopenharmony_ci    PyConfig_InitPythonConfig(&config);
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci    /* pass NULL as the config: config is read from command line arguments,
567db96d56Sopenharmony_ci       environment variables, configuration files */
577db96d56Sopenharmony_ci    if (args->use_bytes_argv) {
587db96d56Sopenharmony_ci        status = PyConfig_SetBytesArgv(&config, args->argc, args->bytes_argv);
597db96d56Sopenharmony_ci    }
607db96d56Sopenharmony_ci    else {
617db96d56Sopenharmony_ci        status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
627db96d56Sopenharmony_ci    }
637db96d56Sopenharmony_ci    if (_PyStatus_EXCEPTION(status)) {
647db96d56Sopenharmony_ci        goto done;
657db96d56Sopenharmony_ci    }
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci    status = Py_InitializeFromConfig(&config);
687db96d56Sopenharmony_ci    if (_PyStatus_EXCEPTION(status)) {
697db96d56Sopenharmony_ci        goto done;
707db96d56Sopenharmony_ci    }
717db96d56Sopenharmony_ci    status = _PyStatus_OK();
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_cidone:
747db96d56Sopenharmony_ci    PyConfig_Clear(&config);
757db96d56Sopenharmony_ci    return status;
767db96d56Sopenharmony_ci}
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ci/* --- pymain_run_python() ---------------------------------------- */
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci/* Non-zero if filename, command (-c) or module (-m) is set
827db96d56Sopenharmony_ci   on the command line */
837db96d56Sopenharmony_cistatic inline int config_run_code(const PyConfig *config)
847db96d56Sopenharmony_ci{
857db96d56Sopenharmony_ci    return (config->run_command != NULL
867db96d56Sopenharmony_ci            || config->run_filename != NULL
877db96d56Sopenharmony_ci            || config->run_module != NULL);
887db96d56Sopenharmony_ci}
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci/* Return non-zero if stdin is a TTY or if -i command line option is used */
927db96d56Sopenharmony_cistatic int
937db96d56Sopenharmony_cistdin_is_interactive(const PyConfig *config)
947db96d56Sopenharmony_ci{
957db96d56Sopenharmony_ci    return (isatty(fileno(stdin)) || config->interactive);
967db96d56Sopenharmony_ci}
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci/* Display the current Python exception and return an exitcode */
1007db96d56Sopenharmony_cistatic int
1017db96d56Sopenharmony_cipymain_err_print(int *exitcode_p)
1027db96d56Sopenharmony_ci{
1037db96d56Sopenharmony_ci    int exitcode;
1047db96d56Sopenharmony_ci    if (_Py_HandleSystemExit(&exitcode)) {
1057db96d56Sopenharmony_ci        *exitcode_p = exitcode;
1067db96d56Sopenharmony_ci        return 1;
1077db96d56Sopenharmony_ci    }
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci    PyErr_Print();
1107db96d56Sopenharmony_ci    return 0;
1117db96d56Sopenharmony_ci}
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_cistatic int
1157db96d56Sopenharmony_cipymain_exit_err_print(void)
1167db96d56Sopenharmony_ci{
1177db96d56Sopenharmony_ci    int exitcode = 1;
1187db96d56Sopenharmony_ci    pymain_err_print(&exitcode);
1197db96d56Sopenharmony_ci    return exitcode;
1207db96d56Sopenharmony_ci}
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_ci/* Write an exitcode into *exitcode and return 1 if we have to exit Python.
1247db96d56Sopenharmony_ci   Return 0 otherwise. */
1257db96d56Sopenharmony_cistatic int
1267db96d56Sopenharmony_cipymain_get_importer(const wchar_t *filename, PyObject **importer_p, int *exitcode)
1277db96d56Sopenharmony_ci{
1287db96d56Sopenharmony_ci    PyObject *sys_path0 = NULL, *importer;
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci    sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename));
1317db96d56Sopenharmony_ci    if (sys_path0 == NULL) {
1327db96d56Sopenharmony_ci        goto error;
1337db96d56Sopenharmony_ci    }
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci    importer = PyImport_GetImporter(sys_path0);
1367db96d56Sopenharmony_ci    if (importer == NULL) {
1377db96d56Sopenharmony_ci        goto error;
1387db96d56Sopenharmony_ci    }
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ci    if (importer == Py_None) {
1417db96d56Sopenharmony_ci        Py_DECREF(sys_path0);
1427db96d56Sopenharmony_ci        Py_DECREF(importer);
1437db96d56Sopenharmony_ci        return 0;
1447db96d56Sopenharmony_ci    }
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci    Py_DECREF(importer);
1477db96d56Sopenharmony_ci    *importer_p = sys_path0;
1487db96d56Sopenharmony_ci    return 0;
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_cierror:
1517db96d56Sopenharmony_ci    Py_XDECREF(sys_path0);
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci    PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n");
1547db96d56Sopenharmony_ci    return pymain_err_print(exitcode);
1557db96d56Sopenharmony_ci}
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_cistatic int
1597db96d56Sopenharmony_cipymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
1607db96d56Sopenharmony_ci{
1617db96d56Sopenharmony_ci    PyObject *sys_path;
1627db96d56Sopenharmony_ci    PyObject *sysdict = interp->sysdict;
1637db96d56Sopenharmony_ci    if (sysdict != NULL) {
1647db96d56Sopenharmony_ci        sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path));
1657db96d56Sopenharmony_ci        if (sys_path == NULL && PyErr_Occurred()) {
1667db96d56Sopenharmony_ci            return -1;
1677db96d56Sopenharmony_ci        }
1687db96d56Sopenharmony_ci    }
1697db96d56Sopenharmony_ci    else {
1707db96d56Sopenharmony_ci        sys_path = NULL;
1717db96d56Sopenharmony_ci    }
1727db96d56Sopenharmony_ci    if (sys_path == NULL) {
1737db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
1747db96d56Sopenharmony_ci        return -1;
1757db96d56Sopenharmony_ci    }
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci    if (PyList_Insert(sys_path, 0, path0)) {
1787db96d56Sopenharmony_ci        return -1;
1797db96d56Sopenharmony_ci    }
1807db96d56Sopenharmony_ci    return 0;
1817db96d56Sopenharmony_ci}
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_cistatic void
1857db96d56Sopenharmony_cipymain_header(const PyConfig *config)
1867db96d56Sopenharmony_ci{
1877db96d56Sopenharmony_ci    if (config->quiet) {
1887db96d56Sopenharmony_ci        return;
1897db96d56Sopenharmony_ci    }
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci    if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) {
1927db96d56Sopenharmony_ci        return;
1937db96d56Sopenharmony_ci    }
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci    fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
1967db96d56Sopenharmony_ci    if (config->site_import) {
1977db96d56Sopenharmony_ci        fprintf(stderr, "%s\n", COPYRIGHT);
1987db96d56Sopenharmony_ci    }
1997db96d56Sopenharmony_ci}
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_cistatic void
2037db96d56Sopenharmony_cipymain_import_readline(const PyConfig *config)
2047db96d56Sopenharmony_ci{
2057db96d56Sopenharmony_ci    if (config->isolated) {
2067db96d56Sopenharmony_ci        return;
2077db96d56Sopenharmony_ci    }
2087db96d56Sopenharmony_ci    if (!config->inspect && config_run_code(config)) {
2097db96d56Sopenharmony_ci        return;
2107db96d56Sopenharmony_ci    }
2117db96d56Sopenharmony_ci    if (!isatty(fileno(stdin))) {
2127db96d56Sopenharmony_ci        return;
2137db96d56Sopenharmony_ci    }
2147db96d56Sopenharmony_ci
2157db96d56Sopenharmony_ci    PyObject *mod = PyImport_ImportModule("readline");
2167db96d56Sopenharmony_ci    if (mod == NULL) {
2177db96d56Sopenharmony_ci        PyErr_Clear();
2187db96d56Sopenharmony_ci    }
2197db96d56Sopenharmony_ci    else {
2207db96d56Sopenharmony_ci        Py_DECREF(mod);
2217db96d56Sopenharmony_ci    }
2227db96d56Sopenharmony_ci    mod = PyImport_ImportModule("rlcompleter");
2237db96d56Sopenharmony_ci    if (mod == NULL) {
2247db96d56Sopenharmony_ci        PyErr_Clear();
2257db96d56Sopenharmony_ci    }
2267db96d56Sopenharmony_ci    else {
2277db96d56Sopenharmony_ci        Py_DECREF(mod);
2287db96d56Sopenharmony_ci    }
2297db96d56Sopenharmony_ci}
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_cistatic int
2337db96d56Sopenharmony_cipymain_run_command(wchar_t *command)
2347db96d56Sopenharmony_ci{
2357db96d56Sopenharmony_ci    PyObject *unicode, *bytes;
2367db96d56Sopenharmony_ci    int ret;
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ci    unicode = PyUnicode_FromWideChar(command, -1);
2397db96d56Sopenharmony_ci    if (unicode == NULL) {
2407db96d56Sopenharmony_ci        goto error;
2417db96d56Sopenharmony_ci    }
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ci    if (PySys_Audit("cpython.run_command", "O", unicode) < 0) {
2447db96d56Sopenharmony_ci        return pymain_exit_err_print();
2457db96d56Sopenharmony_ci    }
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ci    bytes = PyUnicode_AsUTF8String(unicode);
2487db96d56Sopenharmony_ci    Py_DECREF(unicode);
2497db96d56Sopenharmony_ci    if (bytes == NULL) {
2507db96d56Sopenharmony_ci        goto error;
2517db96d56Sopenharmony_ci    }
2527db96d56Sopenharmony_ci
2537db96d56Sopenharmony_ci    PyCompilerFlags cf = _PyCompilerFlags_INIT;
2547db96d56Sopenharmony_ci    cf.cf_flags |= PyCF_IGNORE_COOKIE;
2557db96d56Sopenharmony_ci    ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), &cf);
2567db96d56Sopenharmony_ci    Py_DECREF(bytes);
2577db96d56Sopenharmony_ci    return (ret != 0);
2587db96d56Sopenharmony_ci
2597db96d56Sopenharmony_cierror:
2607db96d56Sopenharmony_ci    PySys_WriteStderr("Unable to decode the command from the command line:\n");
2617db96d56Sopenharmony_ci    return pymain_exit_err_print();
2627db96d56Sopenharmony_ci}
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_cistatic int
2667db96d56Sopenharmony_cipymain_run_module(const wchar_t *modname, int set_argv0)
2677db96d56Sopenharmony_ci{
2687db96d56Sopenharmony_ci    PyObject *module, *runpy, *runmodule, *runargs, *result;
2697db96d56Sopenharmony_ci    if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
2707db96d56Sopenharmony_ci        return pymain_exit_err_print();
2717db96d56Sopenharmony_ci    }
2727db96d56Sopenharmony_ci    runpy = PyImport_ImportModule("runpy");
2737db96d56Sopenharmony_ci    if (runpy == NULL) {
2747db96d56Sopenharmony_ci        fprintf(stderr, "Could not import runpy module\n");
2757db96d56Sopenharmony_ci        return pymain_exit_err_print();
2767db96d56Sopenharmony_ci    }
2777db96d56Sopenharmony_ci    runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
2787db96d56Sopenharmony_ci    if (runmodule == NULL) {
2797db96d56Sopenharmony_ci        fprintf(stderr, "Could not access runpy._run_module_as_main\n");
2807db96d56Sopenharmony_ci        Py_DECREF(runpy);
2817db96d56Sopenharmony_ci        return pymain_exit_err_print();
2827db96d56Sopenharmony_ci    }
2837db96d56Sopenharmony_ci    module = PyUnicode_FromWideChar(modname, wcslen(modname));
2847db96d56Sopenharmony_ci    if (module == NULL) {
2857db96d56Sopenharmony_ci        fprintf(stderr, "Could not convert module name to unicode\n");
2867db96d56Sopenharmony_ci        Py_DECREF(runpy);
2877db96d56Sopenharmony_ci        Py_DECREF(runmodule);
2887db96d56Sopenharmony_ci        return pymain_exit_err_print();
2897db96d56Sopenharmony_ci    }
2907db96d56Sopenharmony_ci    runargs = PyTuple_Pack(2, module, set_argv0 ? Py_True : Py_False);
2917db96d56Sopenharmony_ci    if (runargs == NULL) {
2927db96d56Sopenharmony_ci        fprintf(stderr,
2937db96d56Sopenharmony_ci            "Could not create arguments for runpy._run_module_as_main\n");
2947db96d56Sopenharmony_ci        Py_DECREF(runpy);
2957db96d56Sopenharmony_ci        Py_DECREF(runmodule);
2967db96d56Sopenharmony_ci        Py_DECREF(module);
2977db96d56Sopenharmony_ci        return pymain_exit_err_print();
2987db96d56Sopenharmony_ci    }
2997db96d56Sopenharmony_ci    _Py_UnhandledKeyboardInterrupt = 0;
3007db96d56Sopenharmony_ci    result = PyObject_Call(runmodule, runargs, NULL);
3017db96d56Sopenharmony_ci    if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
3027db96d56Sopenharmony_ci        _Py_UnhandledKeyboardInterrupt = 1;
3037db96d56Sopenharmony_ci    }
3047db96d56Sopenharmony_ci    Py_DECREF(runpy);
3057db96d56Sopenharmony_ci    Py_DECREF(runmodule);
3067db96d56Sopenharmony_ci    Py_DECREF(module);
3077db96d56Sopenharmony_ci    Py_DECREF(runargs);
3087db96d56Sopenharmony_ci    if (result == NULL) {
3097db96d56Sopenharmony_ci        return pymain_exit_err_print();
3107db96d56Sopenharmony_ci    }
3117db96d56Sopenharmony_ci    Py_DECREF(result);
3127db96d56Sopenharmony_ci    return 0;
3137db96d56Sopenharmony_ci}
3147db96d56Sopenharmony_ci
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_cistatic int
3177db96d56Sopenharmony_cipymain_run_file_obj(PyObject *program_name, PyObject *filename,
3187db96d56Sopenharmony_ci                    int skip_source_first_line)
3197db96d56Sopenharmony_ci{
3207db96d56Sopenharmony_ci    if (PySys_Audit("cpython.run_file", "O", filename) < 0) {
3217db96d56Sopenharmony_ci        return pymain_exit_err_print();
3227db96d56Sopenharmony_ci    }
3237db96d56Sopenharmony_ci
3247db96d56Sopenharmony_ci    FILE *fp = _Py_fopen_obj(filename, "rb");
3257db96d56Sopenharmony_ci    if (fp == NULL) {
3267db96d56Sopenharmony_ci        // Ignore the OSError
3277db96d56Sopenharmony_ci        PyErr_Clear();
3287db96d56Sopenharmony_ci        PySys_FormatStderr("%S: can't open file %R: [Errno %d] %s\n",
3297db96d56Sopenharmony_ci                           program_name, filename, errno, strerror(errno));
3307db96d56Sopenharmony_ci        return 2;
3317db96d56Sopenharmony_ci    }
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci    if (skip_source_first_line) {
3347db96d56Sopenharmony_ci        int ch;
3357db96d56Sopenharmony_ci        /* Push back first newline so line numbers remain the same */
3367db96d56Sopenharmony_ci        while ((ch = getc(fp)) != EOF) {
3377db96d56Sopenharmony_ci            if (ch == '\n') {
3387db96d56Sopenharmony_ci                (void)ungetc(ch, fp);
3397db96d56Sopenharmony_ci                break;
3407db96d56Sopenharmony_ci            }
3417db96d56Sopenharmony_ci        }
3427db96d56Sopenharmony_ci    }
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_ci    struct _Py_stat_struct sb;
3457db96d56Sopenharmony_ci    if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) {
3467db96d56Sopenharmony_ci        PySys_FormatStderr("%S: %R is a directory, cannot continue\n",
3477db96d56Sopenharmony_ci                           program_name, filename);
3487db96d56Sopenharmony_ci        fclose(fp);
3497db96d56Sopenharmony_ci        return 1;
3507db96d56Sopenharmony_ci    }
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci    // Call pending calls like signal handlers (SIGINT)
3537db96d56Sopenharmony_ci    if (Py_MakePendingCalls() == -1) {
3547db96d56Sopenharmony_ci        fclose(fp);
3557db96d56Sopenharmony_ci        return pymain_exit_err_print();
3567db96d56Sopenharmony_ci    }
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ci    /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */
3597db96d56Sopenharmony_ci    PyCompilerFlags cf = _PyCompilerFlags_INIT;
3607db96d56Sopenharmony_ci    int run = _PyRun_AnyFileObject(fp, filename, 1, &cf);
3617db96d56Sopenharmony_ci    return (run != 0);
3627db96d56Sopenharmony_ci}
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_cistatic int
3657db96d56Sopenharmony_cipymain_run_file(const PyConfig *config)
3667db96d56Sopenharmony_ci{
3677db96d56Sopenharmony_ci    PyObject *filename = PyUnicode_FromWideChar(config->run_filename, -1);
3687db96d56Sopenharmony_ci    if (filename == NULL) {
3697db96d56Sopenharmony_ci        PyErr_Print();
3707db96d56Sopenharmony_ci        return -1;
3717db96d56Sopenharmony_ci    }
3727db96d56Sopenharmony_ci    PyObject *program_name = PyUnicode_FromWideChar(config->program_name, -1);
3737db96d56Sopenharmony_ci    if (program_name == NULL) {
3747db96d56Sopenharmony_ci        Py_DECREF(filename);
3757db96d56Sopenharmony_ci        PyErr_Print();
3767db96d56Sopenharmony_ci        return -1;
3777db96d56Sopenharmony_ci    }
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci    int res = pymain_run_file_obj(program_name, filename,
3807db96d56Sopenharmony_ci                                  config->skip_source_first_line);
3817db96d56Sopenharmony_ci    Py_DECREF(filename);
3827db96d56Sopenharmony_ci    Py_DECREF(program_name);
3837db96d56Sopenharmony_ci    return res;
3847db96d56Sopenharmony_ci}
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ci
3877db96d56Sopenharmony_cistatic int
3887db96d56Sopenharmony_cipymain_run_startup(PyConfig *config, int *exitcode)
3897db96d56Sopenharmony_ci{
3907db96d56Sopenharmony_ci    int ret;
3917db96d56Sopenharmony_ci    if (!config->use_environment) {
3927db96d56Sopenharmony_ci        return 0;
3937db96d56Sopenharmony_ci    }
3947db96d56Sopenharmony_ci    PyObject *startup = NULL;
3957db96d56Sopenharmony_ci#ifdef MS_WINDOWS
3967db96d56Sopenharmony_ci    const wchar_t *env = _wgetenv(L"PYTHONSTARTUP");
3977db96d56Sopenharmony_ci    if (env == NULL || env[0] == L'\0') {
3987db96d56Sopenharmony_ci        return 0;
3997db96d56Sopenharmony_ci    }
4007db96d56Sopenharmony_ci    startup = PyUnicode_FromWideChar(env, wcslen(env));
4017db96d56Sopenharmony_ci    if (startup == NULL) {
4027db96d56Sopenharmony_ci        goto error;
4037db96d56Sopenharmony_ci    }
4047db96d56Sopenharmony_ci#else
4057db96d56Sopenharmony_ci    const char *env = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
4067db96d56Sopenharmony_ci    if (env == NULL) {
4077db96d56Sopenharmony_ci        return 0;
4087db96d56Sopenharmony_ci    }
4097db96d56Sopenharmony_ci    startup = PyUnicode_DecodeFSDefault(env);
4107db96d56Sopenharmony_ci    if (startup == NULL) {
4117db96d56Sopenharmony_ci        goto error;
4127db96d56Sopenharmony_ci    }
4137db96d56Sopenharmony_ci#endif
4147db96d56Sopenharmony_ci    if (PySys_Audit("cpython.run_startup", "O", startup) < 0) {
4157db96d56Sopenharmony_ci        goto error;
4167db96d56Sopenharmony_ci    }
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci    FILE *fp = _Py_fopen_obj(startup, "r");
4197db96d56Sopenharmony_ci    if (fp == NULL) {
4207db96d56Sopenharmony_ci        int save_errno = errno;
4217db96d56Sopenharmony_ci        PyErr_Clear();
4227db96d56Sopenharmony_ci        PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
4237db96d56Sopenharmony_ci
4247db96d56Sopenharmony_ci        errno = save_errno;
4257db96d56Sopenharmony_ci        PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, startup, NULL);
4267db96d56Sopenharmony_ci        goto error;
4277db96d56Sopenharmony_ci    }
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci    PyCompilerFlags cf = _PyCompilerFlags_INIT;
4307db96d56Sopenharmony_ci    (void) _PyRun_SimpleFileObject(fp, startup, 0, &cf);
4317db96d56Sopenharmony_ci    PyErr_Clear();
4327db96d56Sopenharmony_ci    fclose(fp);
4337db96d56Sopenharmony_ci    ret = 0;
4347db96d56Sopenharmony_ci
4357db96d56Sopenharmony_cidone:
4367db96d56Sopenharmony_ci    Py_XDECREF(startup);
4377db96d56Sopenharmony_ci    return ret;
4387db96d56Sopenharmony_ci
4397db96d56Sopenharmony_cierror:
4407db96d56Sopenharmony_ci    ret = pymain_err_print(exitcode);
4417db96d56Sopenharmony_ci    goto done;
4427db96d56Sopenharmony_ci}
4437db96d56Sopenharmony_ci
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci/* Write an exitcode into *exitcode and return 1 if we have to exit Python.
4467db96d56Sopenharmony_ci   Return 0 otherwise. */
4477db96d56Sopenharmony_cistatic int
4487db96d56Sopenharmony_cipymain_run_interactive_hook(int *exitcode)
4497db96d56Sopenharmony_ci{
4507db96d56Sopenharmony_ci    PyObject *sys, *hook, *result;
4517db96d56Sopenharmony_ci    sys = PyImport_ImportModule("sys");
4527db96d56Sopenharmony_ci    if (sys == NULL) {
4537db96d56Sopenharmony_ci        goto error;
4547db96d56Sopenharmony_ci    }
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci    hook = PyObject_GetAttrString(sys, "__interactivehook__");
4577db96d56Sopenharmony_ci    Py_DECREF(sys);
4587db96d56Sopenharmony_ci    if (hook == NULL) {
4597db96d56Sopenharmony_ci        PyErr_Clear();
4607db96d56Sopenharmony_ci        return 0;
4617db96d56Sopenharmony_ci    }
4627db96d56Sopenharmony_ci
4637db96d56Sopenharmony_ci    if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
4647db96d56Sopenharmony_ci        goto error;
4657db96d56Sopenharmony_ci    }
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ci    result = _PyObject_CallNoArgs(hook);
4687db96d56Sopenharmony_ci    Py_DECREF(hook);
4697db96d56Sopenharmony_ci    if (result == NULL) {
4707db96d56Sopenharmony_ci        goto error;
4717db96d56Sopenharmony_ci    }
4727db96d56Sopenharmony_ci    Py_DECREF(result);
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ci    return 0;
4757db96d56Sopenharmony_ci
4767db96d56Sopenharmony_cierror:
4777db96d56Sopenharmony_ci    PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
4787db96d56Sopenharmony_ci    return pymain_err_print(exitcode);
4797db96d56Sopenharmony_ci}
4807db96d56Sopenharmony_ci
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_cistatic int
4837db96d56Sopenharmony_cipymain_run_stdin(PyConfig *config)
4847db96d56Sopenharmony_ci{
4857db96d56Sopenharmony_ci    if (stdin_is_interactive(config)) {
4867db96d56Sopenharmony_ci        config->inspect = 0;
4877db96d56Sopenharmony_ci        Py_InspectFlag = 0; /* do exit on SystemExit */
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci        int exitcode;
4907db96d56Sopenharmony_ci        if (pymain_run_startup(config, &exitcode)) {
4917db96d56Sopenharmony_ci            return exitcode;
4927db96d56Sopenharmony_ci        }
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_ci        if (pymain_run_interactive_hook(&exitcode)) {
4957db96d56Sopenharmony_ci            return exitcode;
4967db96d56Sopenharmony_ci        }
4977db96d56Sopenharmony_ci    }
4987db96d56Sopenharmony_ci
4997db96d56Sopenharmony_ci    /* call pending calls like signal handlers (SIGINT) */
5007db96d56Sopenharmony_ci    if (Py_MakePendingCalls() == -1) {
5017db96d56Sopenharmony_ci        return pymain_exit_err_print();
5027db96d56Sopenharmony_ci    }
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_ci    if (PySys_Audit("cpython.run_stdin", NULL) < 0) {
5057db96d56Sopenharmony_ci        return pymain_exit_err_print();
5067db96d56Sopenharmony_ci    }
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci    PyCompilerFlags cf = _PyCompilerFlags_INIT;
5097db96d56Sopenharmony_ci    int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
5107db96d56Sopenharmony_ci    return (run != 0);
5117db96d56Sopenharmony_ci}
5127db96d56Sopenharmony_ci
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_cistatic void
5157db96d56Sopenharmony_cipymain_repl(PyConfig *config, int *exitcode)
5167db96d56Sopenharmony_ci{
5177db96d56Sopenharmony_ci    /* Check this environment variable at the end, to give programs the
5187db96d56Sopenharmony_ci       opportunity to set it from Python. */
5197db96d56Sopenharmony_ci    if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
5207db96d56Sopenharmony_ci        config->inspect = 1;
5217db96d56Sopenharmony_ci        Py_InspectFlag = 1;
5227db96d56Sopenharmony_ci    }
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ci    if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
5257db96d56Sopenharmony_ci        return;
5267db96d56Sopenharmony_ci    }
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ci    config->inspect = 0;
5297db96d56Sopenharmony_ci    Py_InspectFlag = 0;
5307db96d56Sopenharmony_ci    if (pymain_run_interactive_hook(exitcode)) {
5317db96d56Sopenharmony_ci        return;
5327db96d56Sopenharmony_ci    }
5337db96d56Sopenharmony_ci
5347db96d56Sopenharmony_ci    PyCompilerFlags cf = _PyCompilerFlags_INIT;
5357db96d56Sopenharmony_ci    int res = PyRun_AnyFileFlags(stdin, "<stdin>", &cf);
5367db96d56Sopenharmony_ci    *exitcode = (res != 0);
5377db96d56Sopenharmony_ci}
5387db96d56Sopenharmony_ci
5397db96d56Sopenharmony_ci
5407db96d56Sopenharmony_cistatic void
5417db96d56Sopenharmony_cipymain_run_python(int *exitcode)
5427db96d56Sopenharmony_ci{
5437db96d56Sopenharmony_ci    PyObject *main_importer_path = NULL;
5447db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
5457db96d56Sopenharmony_ci    /* pymain_run_stdin() modify the config */
5467db96d56Sopenharmony_ci    PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
5477db96d56Sopenharmony_ci
5487db96d56Sopenharmony_ci    /* ensure path config is written into global variables */
5497db96d56Sopenharmony_ci    if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) {
5507db96d56Sopenharmony_ci        goto error;
5517db96d56Sopenharmony_ci    }
5527db96d56Sopenharmony_ci
5537db96d56Sopenharmony_ci    if (config->run_filename != NULL) {
5547db96d56Sopenharmony_ci        /* If filename is a package (ex: directory or ZIP file) which contains
5557db96d56Sopenharmony_ci           __main__.py, main_importer_path is set to filename and will be
5567db96d56Sopenharmony_ci           prepended to sys.path.
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_ci           Otherwise, main_importer_path is left unchanged. */
5597db96d56Sopenharmony_ci        if (pymain_get_importer(config->run_filename, &main_importer_path,
5607db96d56Sopenharmony_ci                                exitcode)) {
5617db96d56Sopenharmony_ci            return;
5627db96d56Sopenharmony_ci        }
5637db96d56Sopenharmony_ci    }
5647db96d56Sopenharmony_ci
5657db96d56Sopenharmony_ci    // import readline and rlcompleter before script dir is added to sys.path
5667db96d56Sopenharmony_ci    pymain_import_readline(config);
5677db96d56Sopenharmony_ci
5687db96d56Sopenharmony_ci    if (main_importer_path != NULL) {
5697db96d56Sopenharmony_ci        if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
5707db96d56Sopenharmony_ci            goto error;
5717db96d56Sopenharmony_ci        }
5727db96d56Sopenharmony_ci    }
5737db96d56Sopenharmony_ci    else if (!config->safe_path) {
5747db96d56Sopenharmony_ci        PyObject *path0 = NULL;
5757db96d56Sopenharmony_ci        int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
5767db96d56Sopenharmony_ci        if (res < 0) {
5777db96d56Sopenharmony_ci            goto error;
5787db96d56Sopenharmony_ci        }
5797db96d56Sopenharmony_ci
5807db96d56Sopenharmony_ci        if (res > 0) {
5817db96d56Sopenharmony_ci            if (pymain_sys_path_add_path0(interp, path0) < 0) {
5827db96d56Sopenharmony_ci                Py_DECREF(path0);
5837db96d56Sopenharmony_ci                goto error;
5847db96d56Sopenharmony_ci            }
5857db96d56Sopenharmony_ci            Py_DECREF(path0);
5867db96d56Sopenharmony_ci        }
5877db96d56Sopenharmony_ci    }
5887db96d56Sopenharmony_ci
5897db96d56Sopenharmony_ci    pymain_header(config);
5907db96d56Sopenharmony_ci
5917db96d56Sopenharmony_ci    if (config->run_command) {
5927db96d56Sopenharmony_ci        *exitcode = pymain_run_command(config->run_command);
5937db96d56Sopenharmony_ci    }
5947db96d56Sopenharmony_ci    else if (config->run_module) {
5957db96d56Sopenharmony_ci        *exitcode = pymain_run_module(config->run_module, 1);
5967db96d56Sopenharmony_ci    }
5977db96d56Sopenharmony_ci    else if (main_importer_path != NULL) {
5987db96d56Sopenharmony_ci        *exitcode = pymain_run_module(L"__main__", 0);
5997db96d56Sopenharmony_ci    }
6007db96d56Sopenharmony_ci    else if (config->run_filename != NULL) {
6017db96d56Sopenharmony_ci        *exitcode = pymain_run_file(config);
6027db96d56Sopenharmony_ci    }
6037db96d56Sopenharmony_ci    else {
6047db96d56Sopenharmony_ci        *exitcode = pymain_run_stdin(config);
6057db96d56Sopenharmony_ci    }
6067db96d56Sopenharmony_ci
6077db96d56Sopenharmony_ci    pymain_repl(config, exitcode);
6087db96d56Sopenharmony_ci    goto done;
6097db96d56Sopenharmony_ci
6107db96d56Sopenharmony_cierror:
6117db96d56Sopenharmony_ci    *exitcode = pymain_exit_err_print();
6127db96d56Sopenharmony_ci
6137db96d56Sopenharmony_cidone:
6147db96d56Sopenharmony_ci    Py_XDECREF(main_importer_path);
6157db96d56Sopenharmony_ci}
6167db96d56Sopenharmony_ci
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci/* --- pymain_main() ---------------------------------------------- */
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_cistatic void
6217db96d56Sopenharmony_cipymain_free(void)
6227db96d56Sopenharmony_ci{
6237db96d56Sopenharmony_ci    _PyImport_Fini2();
6247db96d56Sopenharmony_ci
6257db96d56Sopenharmony_ci    /* Free global variables which cannot be freed in Py_Finalize():
6267db96d56Sopenharmony_ci       configuration options set before Py_Initialize() which should
6277db96d56Sopenharmony_ci       remain valid after Py_Finalize(), since
6287db96d56Sopenharmony_ci       Py_Initialize()-Py_Finalize() can be called multiple times. */
6297db96d56Sopenharmony_ci    _PyPathConfig_ClearGlobal();
6307db96d56Sopenharmony_ci    _Py_ClearStandardStreamEncoding();
6317db96d56Sopenharmony_ci    _Py_ClearArgcArgv();
6327db96d56Sopenharmony_ci    _PyRuntime_Finalize();
6337db96d56Sopenharmony_ci}
6347db96d56Sopenharmony_ci
6357db96d56Sopenharmony_ci
6367db96d56Sopenharmony_cistatic int
6377db96d56Sopenharmony_ciexit_sigint(void)
6387db96d56Sopenharmony_ci{
6397db96d56Sopenharmony_ci    /* bpo-1054041: We need to exit via the
6407db96d56Sopenharmony_ci     * SIG_DFL handler for SIGINT if KeyboardInterrupt went unhandled.
6417db96d56Sopenharmony_ci     * If we don't, a calling process such as a shell may not know
6427db96d56Sopenharmony_ci     * about the user's ^C.  https://www.cons.org/cracauer/sigint.html */
6437db96d56Sopenharmony_ci#if defined(HAVE_GETPID) && defined(HAVE_KILL) && !defined(MS_WINDOWS)
6447db96d56Sopenharmony_ci    if (PyOS_setsig(SIGINT, SIG_DFL) == SIG_ERR) {
6457db96d56Sopenharmony_ci        perror("signal");  /* Impossible in normal environments. */
6467db96d56Sopenharmony_ci    } else {
6477db96d56Sopenharmony_ci        kill(getpid(), SIGINT);
6487db96d56Sopenharmony_ci    }
6497db96d56Sopenharmony_ci    /* If setting SIG_DFL failed, or kill failed to terminate us,
6507db96d56Sopenharmony_ci     * there isn't much else we can do aside from an error code. */
6517db96d56Sopenharmony_ci#endif  /* HAVE_GETPID && !MS_WINDOWS */
6527db96d56Sopenharmony_ci#ifdef MS_WINDOWS
6537db96d56Sopenharmony_ci    /* cmd.exe detects this, prints ^C, and offers to terminate. */
6547db96d56Sopenharmony_ci    /* https://msdn.microsoft.com/en-us/library/cc704588.aspx */
6557db96d56Sopenharmony_ci    return STATUS_CONTROL_C_EXIT;
6567db96d56Sopenharmony_ci#else
6577db96d56Sopenharmony_ci    return SIGINT + 128;
6587db96d56Sopenharmony_ci#endif  /* !MS_WINDOWS */
6597db96d56Sopenharmony_ci}
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ci
6627db96d56Sopenharmony_cistatic void _Py_NO_RETURN
6637db96d56Sopenharmony_cipymain_exit_error(PyStatus status)
6647db96d56Sopenharmony_ci{
6657db96d56Sopenharmony_ci    if (_PyStatus_IS_EXIT(status)) {
6667db96d56Sopenharmony_ci        /* If it's an error rather than a regular exit, leave Python runtime
6677db96d56Sopenharmony_ci           alive: Py_ExitStatusException() uses the current exception and use
6687db96d56Sopenharmony_ci           sys.stdout in this case. */
6697db96d56Sopenharmony_ci        pymain_free();
6707db96d56Sopenharmony_ci    }
6717db96d56Sopenharmony_ci    Py_ExitStatusException(status);
6727db96d56Sopenharmony_ci}
6737db96d56Sopenharmony_ci
6747db96d56Sopenharmony_ci
6757db96d56Sopenharmony_ciint
6767db96d56Sopenharmony_ciPy_RunMain(void)
6777db96d56Sopenharmony_ci{
6787db96d56Sopenharmony_ci    int exitcode = 0;
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci    pymain_run_python(&exitcode);
6817db96d56Sopenharmony_ci
6827db96d56Sopenharmony_ci    if (Py_FinalizeEx() < 0) {
6837db96d56Sopenharmony_ci        /* Value unlikely to be confused with a non-error exit status or
6847db96d56Sopenharmony_ci           other special meaning */
6857db96d56Sopenharmony_ci        exitcode = 120;
6867db96d56Sopenharmony_ci    }
6877db96d56Sopenharmony_ci
6887db96d56Sopenharmony_ci    pymain_free();
6897db96d56Sopenharmony_ci
6907db96d56Sopenharmony_ci    if (_Py_UnhandledKeyboardInterrupt) {
6917db96d56Sopenharmony_ci        exitcode = exit_sigint();
6927db96d56Sopenharmony_ci    }
6937db96d56Sopenharmony_ci
6947db96d56Sopenharmony_ci    return exitcode;
6957db96d56Sopenharmony_ci}
6967db96d56Sopenharmony_ci
6977db96d56Sopenharmony_ci
6987db96d56Sopenharmony_cistatic int
6997db96d56Sopenharmony_cipymain_main(_PyArgv *args)
7007db96d56Sopenharmony_ci{
7017db96d56Sopenharmony_ci    PyStatus status = pymain_init(args);
7027db96d56Sopenharmony_ci    if (_PyStatus_IS_EXIT(status)) {
7037db96d56Sopenharmony_ci        pymain_free();
7047db96d56Sopenharmony_ci        return status.exitcode;
7057db96d56Sopenharmony_ci    }
7067db96d56Sopenharmony_ci    if (_PyStatus_EXCEPTION(status)) {
7077db96d56Sopenharmony_ci        pymain_exit_error(status);
7087db96d56Sopenharmony_ci    }
7097db96d56Sopenharmony_ci
7107db96d56Sopenharmony_ci    return Py_RunMain();
7117db96d56Sopenharmony_ci}
7127db96d56Sopenharmony_ci
7137db96d56Sopenharmony_ci
7147db96d56Sopenharmony_ciint
7157db96d56Sopenharmony_ciPy_Main(int argc, wchar_t **argv)
7167db96d56Sopenharmony_ci{
7177db96d56Sopenharmony_ci    _PyArgv args = {
7187db96d56Sopenharmony_ci        .argc = argc,
7197db96d56Sopenharmony_ci        .use_bytes_argv = 0,
7207db96d56Sopenharmony_ci        .bytes_argv = NULL,
7217db96d56Sopenharmony_ci        .wchar_argv = argv};
7227db96d56Sopenharmony_ci    return pymain_main(&args);
7237db96d56Sopenharmony_ci}
7247db96d56Sopenharmony_ci
7257db96d56Sopenharmony_ci
7267db96d56Sopenharmony_ciint
7277db96d56Sopenharmony_ciPy_BytesMain(int argc, char **argv)
7287db96d56Sopenharmony_ci{
7297db96d56Sopenharmony_ci    _PyArgv args = {
7307db96d56Sopenharmony_ci        .argc = argc,
7317db96d56Sopenharmony_ci        .use_bytes_argv = 1,
7327db96d56Sopenharmony_ci        .bytes_argv = argv,
7337db96d56Sopenharmony_ci        .wchar_argv = NULL};
7347db96d56Sopenharmony_ci    return pymain_main(&args);
7357db96d56Sopenharmony_ci}
7367db96d56Sopenharmony_ci
7377db96d56Sopenharmony_ci#ifdef __cplusplus
7387db96d56Sopenharmony_ci}
7397db96d56Sopenharmony_ci#endif
740