LCOV - code coverage report
Current view: | top level - Modules - main.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 160 | 343 | 46.6 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 18 | 26 | 69.2 %
|  |  | Branches: | 68 | 182 | 37.4 %

               Branch data     Line data    Source code
           1                 :            : /* Python interpreter main program */
           2                 :            :
           3                 :            : #include "Python.h"
           4                 :            : #include "pycore_call.h"          // _PyObject_CallNoArgs()
           5                 :            : #include "pycore_initconfig.h"    // _PyArgv
           6                 :            : #include "pycore_interp.h"        // _PyInterpreterState.sysdict
           7                 :            : #include "pycore_pathconfig.h"    // _PyPathConfig_ComputeSysPath0()
           8                 :            : #include "pycore_pylifecycle.h"   // _Py_PreInitializeFromPyArgv()
           9                 :            : #include "pycore_pystate.h"       // _PyInterpreterState_GET()
          10                 :            :
          11                 :            : /* Includes for exit_sigint() */
          12                 :            : #include <stdio.h>                // perror()
          13                 :            : #ifdef HAVE_SIGNAL_H
          14                 :            : #  include <signal.h>             // SIGINT
          15                 :            : #endif
          16                 :            : #if defined(HAVE_GETPID) && defined(HAVE_UNISTD_H)
          17                 :            : #  include <unistd.h>             // getpid()
          18                 :            : #endif
          19                 :            : #ifdef MS_WINDOWS
          20                 :            : #  include <windows.h>            // STATUS_CONTROL_C_EXIT
          21                 :            : #endif
          22                 :            : /* End of includes for exit_sigint() */
          23                 :            :
          24                 :            : #define COPYRIGHT \
          25                 :            :     "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
          26                 :            :     "for more information."
          27                 :            :
          28                 :            : #ifdef __cplusplus
          29                 :            : extern "C" {
          30                 :            : #endif
          31                 :            :
          32                 :            : /* --- pymain_init() ---------------------------------------------- */
          33                 :            :
          34                 :            : static PyStatus
          35                 :          4 : pymain_init(const _PyArgv *args)
          36                 :            : {
          37                 :            :     PyStatus status;
          38                 :            :
          39                 :          4 :     status = _PyRuntime_Initialize();
          40         [ -  + ]:          4 :     if (_PyStatus_EXCEPTION(status)) {
          41                 :          0 :         return status;
          42                 :            :     }
          43                 :            :
          44                 :            :     PyPreConfig preconfig;
          45                 :          4 :     PyPreConfig_InitPythonConfig(&preconfig);
          46                 :            :
          47                 :          4 :     status = _Py_PreInitializeFromPyArgv(&preconfig, args);
          48         [ -  + ]:          4 :     if (_PyStatus_EXCEPTION(status)) {
          49                 :          0 :         return status;
          50                 :            :     }
          51                 :            :
          52                 :            :     PyConfig config;
          53                 :          4 :     PyConfig_InitPythonConfig(&config);
          54                 :            :
          55                 :            :     /* pass NULL as the config: config is read from command line arguments,
          56                 :            :        environment variables, configuration files */
          57         [ +  - ]:          4 :     if (args->use_bytes_argv) {
          58                 :          4 :         status = PyConfig_SetBytesArgv(&config, args->argc, args->bytes_argv);
          59                 :            :     }
          60                 :            :     else {
          61                 :          0 :         status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
          62                 :            :     }
          63         [ -  + ]:          4 :     if (_PyStatus_EXCEPTION(status)) {
          64                 :          0 :         goto done;
          65                 :            :     }
          66                 :            :
          67                 :          4 :     status = Py_InitializeFromConfig(&config);
          68         [ -  + ]:          4 :     if (_PyStatus_EXCEPTION(status)) {
          69                 :          0 :         goto done;
          70                 :            :     }
          71                 :          4 :     status = _PyStatus_OK();
          72                 :            :
          73                 :          4 : done:
          74                 :          4 :     PyConfig_Clear(&config);
          75                 :          4 :     return status;
          76                 :            : }
          77                 :            :
          78                 :            :
          79                 :            : /* --- pymain_run_python() ---------------------------------------- */
          80                 :            :
          81                 :            : /* Non-zero if filename, command (-c) or module (-m) is set
          82                 :            :    on the command line */
          83                 :         50 : static inline int config_run_code(const PyConfig *config)
          84                 :            : {
          85                 :         50 :     return (config->run_command != NULL
          86         [ +  + ]:         48 :             || config->run_filename != NULL
          87   [ +  +  +  - ]:         98 :             || config->run_module != NULL);
          88                 :            : }
          89                 :            :
          90                 :            :
          91                 :            : /* Return non-zero if stdin is a TTY or if -i command line option is used */
          92                 :            : static int
          93                 :          0 : stdin_is_interactive(const PyConfig *config)
          94                 :            : {
          95   [ #  #  #  # ]:          0 :     return (isatty(fileno(stdin)) || config->interactive);
          96                 :            : }
          97                 :            :
          98                 :            :
          99                 :            : /* Display the current Python exception and return an exitcode */
         100                 :            : static int
         101                 :          1 : pymain_err_print(int *exitcode_p)
         102                 :            : {
         103                 :            :     int exitcode;
         104         [ +  - ]:          1 :     if (_Py_HandleSystemExit(&exitcode)) {
         105                 :          1 :         *exitcode_p = exitcode;
         106                 :          1 :         return 1;
         107                 :            :     }
         108                 :            :
         109                 :          0 :     PyErr_Print();
         110                 :          0 :     return 0;
         111                 :            : }
         112                 :            :
         113                 :            :
         114                 :            : static int
         115                 :          1 : pymain_exit_err_print(void)
         116                 :            : {
         117                 :          1 :     int exitcode = 1;
         118                 :          1 :     pymain_err_print(&exitcode);
         119                 :          1 :     return exitcode;
         120                 :            : }
         121                 :            :
         122                 :            :
         123                 :            : /* Write an exitcode into *exitcode and return 1 if we have to exit Python.
         124                 :            :    Return 0 otherwise. */
         125                 :            : static int
         126                 :         22 : pymain_get_importer(const wchar_t *filename, PyObject **importer_p, int *exitcode)
         127                 :            : {
         128                 :         22 :     PyObject *sys_path0 = NULL, *importer;
         129                 :            :
         130                 :         22 :     sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename));
         131         [ -  + ]:         22 :     if (sys_path0 == NULL) {
         132                 :          0 :         goto error;
         133                 :            :     }
         134                 :            :
         135                 :         22 :     importer = PyImport_GetImporter(sys_path0);
         136         [ -  + ]:         22 :     if (importer == NULL) {
         137                 :          0 :         goto error;
         138                 :            :     }
         139                 :            :
         140         [ +  - ]:         22 :     if (importer == Py_None) {
         141                 :         22 :         Py_DECREF(sys_path0);
         142                 :         22 :         Py_DECREF(importer);
         143                 :         22 :         return 0;
         144                 :            :     }
         145                 :            :
         146                 :          0 :     Py_DECREF(importer);
         147                 :          0 :     *importer_p = sys_path0;
         148                 :          0 :     return 0;
         149                 :            :
         150                 :          0 : error:
         151                 :          0 :     Py_XDECREF(sys_path0);
         152                 :            :
         153                 :          0 :     PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n");
         154                 :          0 :     return pymain_err_print(exitcode);
         155                 :            : }
         156                 :            :
         157                 :            :
         158                 :            : static int
         159                 :         25 : pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
         160                 :            : {
         161                 :            :     PyObject *sys_path;
         162                 :         25 :     PyObject *sysdict = interp->sysdict;
         163         [ +  - ]:         25 :     if (sysdict != NULL) {
         164                 :         25 :         sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path));
         165   [ -  +  -  - ]:         25 :         if (sys_path == NULL && PyErr_Occurred()) {
         166                 :          0 :             return -1;
         167                 :            :         }
         168                 :            :     }
         169                 :            :     else {
         170                 :          0 :         sys_path = NULL;
         171                 :            :     }
         172         [ -  + ]:         25 :     if (sys_path == NULL) {
         173                 :          0 :         PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
         174                 :          0 :         return -1;
         175                 :            :     }
         176                 :            :
         177         [ -  + ]:         25 :     if (PyList_Insert(sys_path, 0, path0)) {
         178                 :          0 :         return -1;
         179                 :            :     }
         180                 :         25 :     return 0;
         181                 :            : }
         182                 :            :
         183                 :            :
         184                 :            : static void
         185                 :         25 : pymain_header(const PyConfig *config)
         186                 :            : {
         187         [ -  + ]:         25 :     if (config->quiet) {
         188                 :          0 :         return;
         189                 :            :     }
         190                 :            :
         191   [ +  -  -  +  :         25 :     if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) {
                       -  - ]
         192                 :         25 :         return;
         193                 :            :     }
         194                 :            :
         195                 :          0 :     fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
         196         [ #  # ]:          0 :     if (config->site_import) {
         197                 :          0 :         fprintf(stderr, "%s\n", COPYRIGHT);
         198                 :            :     }
         199                 :            : }
         200                 :            :
         201                 :            :
         202                 :            : static void
         203                 :         25 : pymain_import_readline(const PyConfig *config)
         204                 :            : {
         205         [ -  + ]:         25 :     if (config->isolated) {
         206                 :          0 :         return;
         207                 :            :     }
         208   [ +  -  +  - ]:         25 :     if (!config->inspect && config_run_code(config)) {
         209                 :         25 :         return;
         210                 :            :     }
         211         [ #  # ]:          0 :     if (!isatty(fileno(stdin))) {
         212                 :          0 :         return;
         213                 :            :     }
         214                 :            :
         215                 :          0 :     PyObject *mod = PyImport_ImportModule("readline");
         216         [ #  # ]:          0 :     if (mod == NULL) {
         217                 :          0 :         PyErr_Clear();
         218                 :            :     }
         219                 :            :     else {
         220                 :          0 :         Py_DECREF(mod);
         221                 :            :     }
         222                 :          0 :     mod = PyImport_ImportModule("rlcompleter");
         223         [ #  # ]:          0 :     if (mod == NULL) {
         224                 :          0 :         PyErr_Clear();
         225                 :            :     }
         226                 :            :     else {
         227                 :          0 :         Py_DECREF(mod);
         228                 :            :     }
         229                 :            : }
         230                 :            :
         231                 :            :
         232                 :            : static int
         233                 :          1 : pymain_run_command(wchar_t *command)
         234                 :            : {
         235                 :            :     PyObject *unicode, *bytes;
         236                 :            :     int ret;
         237                 :            :
         238                 :          1 :     unicode = PyUnicode_FromWideChar(command, -1);
         239         [ -  + ]:          1 :     if (unicode == NULL) {
         240                 :          0 :         goto error;
         241                 :            :     }
         242                 :            :
         243         [ -  + ]:          1 :     if (PySys_Audit("cpython.run_command", "O", unicode) < 0) {
         244                 :          0 :         return pymain_exit_err_print();
         245                 :            :     }
         246                 :            :
         247                 :          1 :     bytes = PyUnicode_AsUTF8String(unicode);
         248                 :          1 :     Py_DECREF(unicode);
         249         [ -  + ]:          1 :     if (bytes == NULL) {
         250                 :          0 :         goto error;
         251                 :            :     }
         252                 :            :
         253                 :          1 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
         254                 :          1 :     cf.cf_flags |= PyCF_IGNORE_COOKIE;
         255                 :          1 :     ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), &cf);
         256                 :          1 :     Py_DECREF(bytes);
         257                 :          1 :     return (ret != 0);
         258                 :            :
         259                 :          0 : error:
         260                 :          0 :     PySys_WriteStderr("Unable to decode the command from the command line:\n");
         261                 :          0 :     return pymain_exit_err_print();
         262                 :            : }
         263                 :            :
         264                 :            :
         265                 :            : static int
         266                 :          2 : pymain_run_module(const wchar_t *modname, int set_argv0)
         267                 :            : {
         268                 :            :     PyObject *module, *runpy, *runmodule, *runargs, *result;
         269         [ -  + ]:          2 :     if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
         270                 :          0 :         return pymain_exit_err_print();
         271                 :            :     }
         272                 :          2 :     runpy = PyImport_ImportModule("runpy");
         273         [ -  + ]:          2 :     if (runpy == NULL) {
         274                 :          0 :         fprintf(stderr, "Could not import runpy module\n");
         275                 :          0 :         return pymain_exit_err_print();
         276                 :            :     }
         277                 :          2 :     runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
         278         [ -  + ]:          2 :     if (runmodule == NULL) {
         279                 :          0 :         fprintf(stderr, "Could not access runpy._run_module_as_main\n");
         280                 :          0 :         Py_DECREF(runpy);
         281                 :          0 :         return pymain_exit_err_print();
         282                 :            :     }
         283                 :          2 :     module = PyUnicode_FromWideChar(modname, wcslen(modname));
         284         [ -  + ]:          2 :     if (module == NULL) {
         285                 :          0 :         fprintf(stderr, "Could not convert module name to unicode\n");
         286                 :          0 :         Py_DECREF(runpy);
         287                 :          0 :         Py_DECREF(runmodule);
         288                 :          0 :         return pymain_exit_err_print();
         289                 :            :     }
         290         [ +  - ]:          2 :     runargs = PyTuple_Pack(2, module, set_argv0 ? Py_True : Py_False);
         291         [ -  + ]:          2 :     if (runargs == NULL) {
         292                 :          0 :         fprintf(stderr,
         293                 :            :             "Could not create arguments for runpy._run_module_as_main\n");
         294                 :          0 :         Py_DECREF(runpy);
         295                 :          0 :         Py_DECREF(runmodule);
         296                 :          0 :         Py_DECREF(module);
         297                 :          0 :         return pymain_exit_err_print();
         298                 :            :     }
         299                 :          2 :     _PyRuntime.signals.unhandled_keyboard_interrupt = 0;
         300                 :          2 :     result = PyObject_Call(runmodule, runargs, NULL);
         301   [ +  +  -  + ]:          2 :     if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
         302                 :          0 :         _PyRuntime.signals.unhandled_keyboard_interrupt = 1;
         303                 :            :     }
         304                 :          2 :     Py_DECREF(runpy);
         305                 :          2 :     Py_DECREF(runmodule);
         306                 :          2 :     Py_DECREF(module);
         307                 :          2 :     Py_DECREF(runargs);
         308         [ +  + ]:          2 :     if (result == NULL) {
         309                 :          1 :         return pymain_exit_err_print();
         310                 :            :     }
         311                 :          1 :     Py_DECREF(result);
         312                 :          1 :     return 0;
         313                 :            : }
         314                 :            :
         315                 :            :
         316                 :            : static int
         317                 :         22 : pymain_run_file_obj(PyObject *program_name, PyObject *filename,
         318                 :            :                     int skip_source_first_line)
         319                 :            : {
         320         [ -  + ]:         22 :     if (PySys_Audit("cpython.run_file", "O", filename) < 0) {
         321                 :          0 :         return pymain_exit_err_print();
         322                 :            :     }
         323                 :            :
         324                 :         22 :     FILE *fp = _Py_fopen_obj(filename, "rb");
         325         [ -  + ]:         22 :     if (fp == NULL) {
         326                 :            :         // Ignore the OSError
         327                 :          0 :         PyErr_Clear();
         328                 :          0 :         PySys_FormatStderr("%S: can't open file %R: [Errno %d] %s\n",
         329                 :          0 :                            program_name, filename, errno, strerror(errno));
         330                 :          0 :         return 2;
         331                 :            :     }
         332                 :            :
         333         [ -  + ]:         22 :     if (skip_source_first_line) {
         334                 :            :         int ch;
         335                 :            :         /* Push back first newline so line numbers remain the same */
         336         [ #  # ]:          0 :         while ((ch = getc(fp)) != EOF) {
         337         [ #  # ]:          0 :             if (ch == '\n') {
         338                 :          0 :                 (void)ungetc(ch, fp);
         339                 :          0 :                 break;
         340                 :            :             }
         341                 :            :         }
         342                 :            :     }
         343                 :            :
         344                 :            :     struct _Py_stat_struct sb;
         345   [ +  -  -  + ]:         22 :     if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) {
         346                 :          0 :         PySys_FormatStderr("%S: %R is a directory, cannot continue\n",
         347                 :            :                            program_name, filename);
         348                 :          0 :         fclose(fp);
         349                 :          0 :         return 1;
         350                 :            :     }
         351                 :            :
         352                 :            :     // Call pending calls like signal handlers (SIGINT)
         353         [ -  + ]:         22 :     if (Py_MakePendingCalls() == -1) {
         354                 :          0 :         fclose(fp);
         355                 :          0 :         return pymain_exit_err_print();
         356                 :            :     }
         357                 :            :
         358                 :            :     /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */
         359                 :         22 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
         360                 :         22 :     int run = _PyRun_AnyFileObject(fp, filename, 1, &cf);
         361                 :         22 :     return (run != 0);
         362                 :            : }
         363                 :            :
         364                 :            : static int
         365                 :         22 : pymain_run_file(const PyConfig *config)
         366                 :            : {
         367                 :         22 :     PyObject *filename = PyUnicode_FromWideChar(config->run_filename, -1);
         368         [ -  + ]:         22 :     if (filename == NULL) {
         369                 :          0 :         PyErr_Print();
         370                 :          0 :         return -1;
         371                 :            :     }
         372                 :         22 :     PyObject *program_name = PyUnicode_FromWideChar(config->program_name, -1);
         373         [ -  + ]:         22 :     if (program_name == NULL) {
         374                 :          0 :         Py_DECREF(filename);
         375                 :          0 :         PyErr_Print();
         376                 :          0 :         return -1;
         377                 :            :     }
         378                 :            :
         379                 :         22 :     int res = pymain_run_file_obj(program_name, filename,
         380                 :            :                                   config->skip_source_first_line);
         381                 :         22 :     Py_DECREF(filename);
         382                 :         22 :     Py_DECREF(program_name);
         383                 :         22 :     return res;
         384                 :            : }
         385                 :            :
         386                 :            :
         387                 :            : static int
         388                 :          0 : pymain_run_startup(PyConfig *config, int *exitcode)
         389                 :            : {
         390                 :            :     int ret;
         391         [ #  # ]:          0 :     if (!config->use_environment) {
         392                 :          0 :         return 0;
         393                 :            :     }
         394                 :          0 :     PyObject *startup = NULL;
         395                 :            : #ifdef MS_WINDOWS
         396                 :            :     const wchar_t *env = _wgetenv(L"PYTHONSTARTUP");
         397                 :            :     if (env == NULL || env[0] == L'\0') {
         398                 :            :         return 0;
         399                 :            :     }
         400                 :            :     startup = PyUnicode_FromWideChar(env, wcslen(env));
         401                 :            :     if (startup == NULL) {
         402                 :            :         goto error;
         403                 :            :     }
         404                 :            : #else
         405                 :          0 :     const char *env = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
         406         [ #  # ]:          0 :     if (env == NULL) {
         407                 :          0 :         return 0;
         408                 :            :     }
         409                 :          0 :     startup = PyUnicode_DecodeFSDefault(env);
         410         [ #  # ]:          0 :     if (startup == NULL) {
         411                 :          0 :         goto error;
         412                 :            :     }
         413                 :            : #endif
         414         [ #  # ]:          0 :     if (PySys_Audit("cpython.run_startup", "O", startup) < 0) {
         415                 :          0 :         goto error;
         416                 :            :     }
         417                 :            :
         418                 :          0 :     FILE *fp = _Py_fopen_obj(startup, "r");
         419         [ #  # ]:          0 :     if (fp == NULL) {
         420                 :          0 :         int save_errno = errno;
         421                 :          0 :         PyErr_Clear();
         422                 :          0 :         PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
         423                 :            :
         424                 :          0 :         errno = save_errno;
         425                 :          0 :         PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, startup, NULL);
         426                 :          0 :         goto error;
         427                 :            :     }
         428                 :            :
         429                 :          0 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
         430                 :          0 :     (void) _PyRun_SimpleFileObject(fp, startup, 0, &cf);
         431                 :          0 :     PyErr_Clear();
         432                 :          0 :     fclose(fp);
         433                 :          0 :     ret = 0;
         434                 :            :
         435                 :          0 : done:
         436                 :          0 :     Py_XDECREF(startup);
         437                 :          0 :     return ret;
         438                 :            :
         439                 :          0 : error:
         440                 :          0 :     ret = pymain_err_print(exitcode);
         441                 :          0 :     goto done;
         442                 :            : }
         443                 :            :
         444                 :            :
         445                 :            : /* Write an exitcode into *exitcode and return 1 if we have to exit Python.
         446                 :            :    Return 0 otherwise. */
         447                 :            : static int
         448                 :          0 : pymain_run_interactive_hook(int *exitcode)
         449                 :            : {
         450                 :            :     PyObject *sys, *hook, *result;
         451                 :          0 :     sys = PyImport_ImportModule("sys");
         452         [ #  # ]:          0 :     if (sys == NULL) {
         453                 :          0 :         goto error;
         454                 :            :     }
         455                 :            :
         456                 :          0 :     hook = PyObject_GetAttrString(sys, "__interactivehook__");
         457                 :          0 :     Py_DECREF(sys);
         458         [ #  # ]:          0 :     if (hook == NULL) {
         459                 :          0 :         PyErr_Clear();
         460                 :          0 :         return 0;
         461                 :            :     }
         462                 :            :
         463         [ #  # ]:          0 :     if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
         464                 :          0 :         goto error;
         465                 :            :     }
         466                 :            :
         467                 :          0 :     result = _PyObject_CallNoArgs(hook);
         468                 :          0 :     Py_DECREF(hook);
         469         [ #  # ]:          0 :     if (result == NULL) {
         470                 :          0 :         goto error;
         471                 :            :     }
         472                 :          0 :     Py_DECREF(result);
         473                 :            :
         474                 :          0 :     return 0;
         475                 :            :
         476                 :          0 : error:
         477                 :          0 :     PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
         478                 :          0 :     return pymain_err_print(exitcode);
         479                 :            : }
         480                 :            :
         481                 :            :
         482                 :            : static void
         483                 :          0 : pymain_set_inspect(PyConfig *config, int inspect)
         484                 :            : {
         485                 :          0 :     config->inspect = inspect;
         486                 :            : _Py_COMP_DIAG_PUSH
         487                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
         488                 :          0 :     Py_InspectFlag = inspect;
         489                 :            : _Py_COMP_DIAG_POP
         490                 :          0 : }
         491                 :            :
         492                 :            :
         493                 :            : static int
         494                 :          0 : pymain_run_stdin(PyConfig *config)
         495                 :            : {
         496         [ #  # ]:          0 :     if (stdin_is_interactive(config)) {
         497                 :            :         // do exit on SystemExit
         498                 :          0 :         pymain_set_inspect(config, 0);
         499                 :            :
         500                 :            :         int exitcode;
         501         [ #  # ]:          0 :         if (pymain_run_startup(config, &exitcode)) {
         502                 :          0 :             return exitcode;
         503                 :            :         }
         504                 :            :
         505         [ #  # ]:          0 :         if (pymain_run_interactive_hook(&exitcode)) {
         506                 :          0 :             return exitcode;
         507                 :            :         }
         508                 :            :     }
         509                 :            :
         510                 :            :     /* call pending calls like signal handlers (SIGINT) */
         511         [ #  # ]:          0 :     if (Py_MakePendingCalls() == -1) {
         512                 :          0 :         return pymain_exit_err_print();
         513                 :            :     }
         514                 :            :
         515         [ #  # ]:          0 :     if (PySys_Audit("cpython.run_stdin", NULL) < 0) {
         516                 :          0 :         return pymain_exit_err_print();
         517                 :            :     }
         518                 :            :
         519                 :          0 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
         520                 :          0 :     int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
         521                 :          0 :     return (run != 0);
         522                 :            : }
         523                 :            :
         524                 :            :
         525                 :            : static void
         526                 :         25 : pymain_repl(PyConfig *config, int *exitcode)
         527                 :            : {
         528                 :            :     /* Check this environment variable at the end, to give programs the
         529                 :            :        opportunity to set it from Python. */
         530   [ +  -  -  + ]:         25 :     if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
         531                 :          0 :         pymain_set_inspect(config, 1);
         532                 :            :     }
         533                 :            :
         534   [ -  +  -  -  :         25 :     if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
                       -  - ]
         535                 :         25 :         return;
         536                 :            :     }
         537                 :            :
         538                 :          0 :     pymain_set_inspect(config, 0);
         539         [ #  # ]:          0 :     if (pymain_run_interactive_hook(exitcode)) {
         540                 :          0 :         return;
         541                 :            :     }
         542                 :            :
         543                 :          0 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
         544                 :          0 :     int res = PyRun_AnyFileFlags(stdin, "<stdin>", &cf);
         545                 :          0 :     *exitcode = (res != 0);
         546                 :            : }
         547                 :            :
         548                 :            :
         549                 :            : static void
         550                 :         25 : pymain_run_python(int *exitcode)
         551                 :            : {
         552                 :         25 :     PyObject *main_importer_path = NULL;
         553                 :         25 :     PyInterpreterState *interp = _PyInterpreterState_GET();
         554                 :            :     /* pymain_run_stdin() modify the config */
         555                 :         25 :     PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
         556                 :            :
         557                 :            :     /* ensure path config is written into global variables */
         558         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) {
         559                 :          0 :         goto error;
         560                 :            :     }
         561                 :            :
         562         [ +  + ]:         25 :     if (config->run_filename != NULL) {
         563                 :            :         /* If filename is a package (ex: directory or ZIP file) which contains
         564                 :            :            __main__.py, main_importer_path is set to filename and will be
         565                 :            :            prepended to sys.path.
         566                 :            :
         567                 :            :            Otherwise, main_importer_path is left unchanged. */
         568         [ -  + ]:         22 :         if (pymain_get_importer(config->run_filename, &main_importer_path,
         569                 :            :                                 exitcode)) {
         570                 :          0 :             return;
         571                 :            :         }
         572                 :            :     }
         573                 :            :
         574                 :            :     // import readline and rlcompleter before script dir is added to sys.path
         575                 :         25 :     pymain_import_readline(config);
         576                 :            :
         577         [ -  + ]:         25 :     if (main_importer_path != NULL) {
         578         [ #  # ]:          0 :         if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
         579                 :          0 :             goto error;
         580                 :            :         }
         581                 :            :     }
         582         [ +  - ]:         25 :     else if (!config->safe_path) {
         583                 :         25 :         PyObject *path0 = NULL;
         584                 :         25 :         int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
         585         [ -  + ]:         25 :         if (res < 0) {
         586                 :          0 :             goto error;
         587                 :            :         }
         588                 :            :
         589         [ +  - ]:         25 :         if (res > 0) {
         590         [ -  + ]:         25 :             if (pymain_sys_path_add_path0(interp, path0) < 0) {
         591                 :          0 :                 Py_DECREF(path0);
         592                 :          0 :                 goto error;
         593                 :            :             }
         594                 :         25 :             Py_DECREF(path0);
         595                 :            :         }
         596                 :            :     }
         597                 :            :
         598                 :         25 :     pymain_header(config);
         599                 :            :
         600         [ +  + ]:         25 :     if (config->run_command) {
         601                 :          1 :         *exitcode = pymain_run_command(config->run_command);
         602                 :            :     }
         603         [ +  + ]:         24 :     else if (config->run_module) {
         604                 :          2 :         *exitcode = pymain_run_module(config->run_module, 1);
         605                 :            :     }
         606         [ -  + ]:         22 :     else if (main_importer_path != NULL) {
         607                 :          0 :         *exitcode = pymain_run_module(L"__main__", 0);
         608                 :            :     }
         609         [ +  - ]:         22 :     else if (config->run_filename != NULL) {
         610                 :         22 :         *exitcode = pymain_run_file(config);
         611                 :            :     }
         612                 :            :     else {
         613                 :          0 :         *exitcode = pymain_run_stdin(config);
         614                 :            :     }
         615                 :            :
         616                 :         25 :     pymain_repl(config, exitcode);
         617                 :         25 :     goto done;
         618                 :            :
         619                 :          0 : error:
         620                 :          0 :     *exitcode = pymain_exit_err_print();
         621                 :            :
         622                 :         25 : done:
         623                 :         25 :     Py_XDECREF(main_importer_path);
         624                 :            : }
         625                 :            :
         626                 :            :
         627                 :            : /* --- pymain_main() ---------------------------------------------- */
         628                 :            :
         629                 :            : static void
         630                 :         25 : pymain_free(void)
         631                 :            : {
         632                 :         25 :     _PyImport_Fini2();
         633                 :            :
         634                 :            :     /* Free global variables which cannot be freed in Py_Finalize():
         635                 :            :        configuration options set before Py_Initialize() which should
         636                 :            :        remain valid after Py_Finalize(), since
         637                 :            :        Py_Initialize()-Py_Finalize() can be called multiple times. */
         638                 :         25 :     _PyPathConfig_ClearGlobal();
         639                 :         25 :     _Py_ClearStandardStreamEncoding();
         640                 :         25 :     _Py_ClearArgcArgv();
         641                 :         25 :     _PyRuntime_Finalize();
         642                 :         25 : }
         643                 :            :
         644                 :            :
         645                 :            : static int
         646                 :          0 : exit_sigint(void)
         647                 :            : {
         648                 :            :     /* bpo-1054041: We need to exit via the
         649                 :            :      * SIG_DFL handler for SIGINT if KeyboardInterrupt went unhandled.
         650                 :            :      * If we don't, a calling process such as a shell may not know
         651                 :            :      * about the user's ^C.  https://www.cons.org/cracauer/sigint.html */
         652                 :            : #if defined(HAVE_GETPID) && defined(HAVE_KILL) && !defined(MS_WINDOWS)
         653         [ #  # ]:          0 :     if (PyOS_setsig(SIGINT, SIG_DFL) == SIG_ERR) {
         654                 :          0 :         perror("signal");  /* Impossible in normal environments. */
         655                 :            :     } else {
         656                 :          0 :         kill(getpid(), SIGINT);
         657                 :            :     }
         658                 :            :     /* If setting SIG_DFL failed, or kill failed to terminate us,
         659                 :            :      * there isn't much else we can do aside from an error code. */
         660                 :            : #endif  /* HAVE_GETPID && !MS_WINDOWS */
         661                 :            : #ifdef MS_WINDOWS
         662                 :            :     /* cmd.exe detects this, prints ^C, and offers to terminate. */
         663                 :            :     /* https://msdn.microsoft.com/en-us/library/cc704588.aspx */
         664                 :            :     return STATUS_CONTROL_C_EXIT;
         665                 :            : #else
         666                 :          0 :     return SIGINT + 128;
         667                 :            : #endif  /* !MS_WINDOWS */
         668                 :            : }
         669                 :            :
         670                 :            :
         671                 :            : static void _Py_NO_RETURN
         672                 :          0 : pymain_exit_error(PyStatus status)
         673                 :            : {
         674         [ #  # ]:          0 :     if (_PyStatus_IS_EXIT(status)) {
         675                 :            :         /* If it's an error rather than a regular exit, leave Python runtime
         676                 :            :            alive: Py_ExitStatusException() uses the current exception and use
         677                 :            :            sys.stdout in this case. */
         678                 :          0 :         pymain_free();
         679                 :            :     }
         680                 :          0 :     Py_ExitStatusException(status);
         681                 :            : }
         682                 :            :
         683                 :            :
         684                 :            : int
         685                 :         25 : Py_RunMain(void)
         686                 :            : {
         687                 :         25 :     int exitcode = 0;
         688                 :            :
         689                 :         25 :     pymain_run_python(&exitcode);
         690                 :            :
         691         [ -  + ]:         25 :     if (Py_FinalizeEx() < 0) {
         692                 :            :         /* Value unlikely to be confused with a non-error exit status or
         693                 :            :            other special meaning */
         694                 :          0 :         exitcode = 120;
         695                 :            :     }
         696                 :            :
         697                 :         25 :     pymain_free();
         698                 :            :
         699         [ -  + ]:         25 :     if (_PyRuntime.signals.unhandled_keyboard_interrupt) {
         700                 :          0 :         exitcode = exit_sigint();
         701                 :            :     }
         702                 :            :
         703                 :         25 :     return exitcode;
         704                 :            : }
         705                 :            :
         706                 :            :
         707                 :            : static int
         708                 :          4 : pymain_main(_PyArgv *args)
         709                 :            : {
         710                 :          4 :     PyStatus status = pymain_init(args);
         711         [ -  + ]:          4 :     if (_PyStatus_IS_EXIT(status)) {
         712                 :          0 :         pymain_free();
         713                 :          0 :         return status.exitcode;
         714                 :            :     }
         715         [ -  + ]:          4 :     if (_PyStatus_EXCEPTION(status)) {
         716                 :          0 :         pymain_exit_error(status);
         717                 :            :     }
         718                 :            :
         719                 :          4 :     return Py_RunMain();
         720                 :            : }
         721                 :            :
         722                 :            :
         723                 :            : int
         724                 :          0 : Py_Main(int argc, wchar_t **argv)
         725                 :            : {
         726                 :          0 :     _PyArgv args = {
         727                 :            :         .argc = argc,
         728                 :            :         .use_bytes_argv = 0,
         729                 :            :         .bytes_argv = NULL,
         730                 :            :         .wchar_argv = argv};
         731                 :          0 :     return pymain_main(&args);
         732                 :            : }
         733                 :            :
         734                 :            :
         735                 :            : int
         736                 :          4 : Py_BytesMain(int argc, char **argv)
         737                 :            : {
         738                 :          4 :     _PyArgv args = {
         739                 :            :         .argc = argc,
         740                 :            :         .use_bytes_argv = 1,
         741                 :            :         .bytes_argv = argv,
         742                 :            :         .wchar_argv = NULL};
         743                 :          4 :     return pymain_main(&args);
         744                 :            : }
         745                 :            :
         746                 :            : #ifdef __cplusplus
         747                 :            : }
         748                 :            : #endif

Generated by: LCOV version 1.14