LCOV - code coverage report
Current view: top level - Modules - main.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 258 344 75.0 %
Date: 2022-07-20 13:12:14 Functions: 25 26 96.2 %
Branches: 127 182 69.8 %

           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                 :       2868 : pymain_init(const _PyArgv *args)
      36                 :            : {
      37                 :            :     PyStatus status;
      38                 :            : 
      39                 :       2868 :     status = _PyRuntime_Initialize();
      40         [ -  + ]:       2868 :     if (_PyStatus_EXCEPTION(status)) {
      41                 :          0 :         return status;
      42                 :            :     }
      43                 :            : 
      44                 :            :     PyPreConfig preconfig;
      45                 :       2868 :     PyPreConfig_InitPythonConfig(&preconfig);
      46                 :            : 
      47                 :       2868 :     status = _Py_PreInitializeFromPyArgv(&preconfig, args);
      48         [ +  + ]:       2868 :     if (_PyStatus_EXCEPTION(status)) {
      49                 :          1 :         return status;
      50                 :            :     }
      51                 :            : 
      52                 :            :     PyConfig config;
      53                 :       2867 :     PyConfig_InitPythonConfig(&config);
      54                 :            : 
      55                 :            :     /* pass NULL as the config: config is read from command line arguments,
      56                 :            :        environment variables, configuration files */
      57         [ +  + ]:       2867 :     if (args->use_bytes_argv) {
      58                 :       2864 :         status = PyConfig_SetBytesArgv(&config, args->argc, args->bytes_argv);
      59                 :            :     }
      60                 :            :     else {
      61                 :          3 :         status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
      62                 :            :     }
      63         [ -  + ]:       2867 :     if (_PyStatus_EXCEPTION(status)) {
      64                 :          0 :         goto done;
      65                 :            :     }
      66                 :            : 
      67                 :       2867 :     status = Py_InitializeFromConfig(&config);
      68         [ +  + ]:       2867 :     if (_PyStatus_EXCEPTION(status)) {
      69                 :         22 :         goto done;
      70                 :            :     }
      71                 :       2845 :     status = _PyStatus_OK();
      72                 :            : 
      73                 :       2867 : done:
      74                 :       2867 :     PyConfig_Clear(&config);
      75                 :       2867 :     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                 :       5072 : static inline int config_run_code(const PyConfig *config)
      84                 :            : {
      85                 :       5072 :     return (config->run_command != NULL
      86         [ +  + ]:       2128 :             || config->run_filename != NULL
      87   [ +  +  +  + ]:       7200 :             || 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                 :         49 : stdin_is_interactive(const PyConfig *config)
      94                 :            : {
      95   [ +  +  +  + ]:         49 :     return (isatty(fileno(stdin)) || config->interactive);
      96                 :            : }
      97                 :            : 
      98                 :            : 
      99                 :            : /* Display the current Python exception and return an exitcode */
     100                 :            : static int
     101                 :        736 : pymain_err_print(int *exitcode_p)
     102                 :            : {
     103                 :            :     int exitcode;
     104         [ +  + ]:        736 :     if (_Py_HandleSystemExit(&exitcode)) {
     105                 :        712 :         *exitcode_p = exitcode;
     106                 :        712 :         return 1;
     107                 :            :     }
     108                 :            : 
     109                 :         24 :     PyErr_Print();
     110                 :         24 :     return 0;
     111                 :            : }
     112                 :            : 
     113                 :            : 
     114                 :            : static int
     115                 :        736 : pymain_exit_err_print(void)
     116                 :            : {
     117                 :        736 :     int exitcode = 1;
     118                 :        736 :     pymain_err_print(&exitcode);
     119                 :        736 :     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                 :        366 : pymain_get_importer(const wchar_t *filename, PyObject **importer_p, int *exitcode)
     127                 :            : {
     128                 :        366 :     PyObject *sys_path0 = NULL, *importer;
     129                 :            : 
     130                 :        366 :     sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename));
     131         [ -  + ]:        366 :     if (sys_path0 == NULL) {
     132                 :          0 :         goto error;
     133                 :            :     }
     134                 :            : 
     135                 :        366 :     importer = PyImport_GetImporter(sys_path0);
     136         [ -  + ]:        366 :     if (importer == NULL) {
     137                 :          0 :         goto error;
     138                 :            :     }
     139                 :            : 
     140         [ +  + ]:        366 :     if (importer == Py_None) {
     141                 :        341 :         Py_DECREF(sys_path0);
     142                 :        341 :         Py_DECREF(importer);
     143                 :        341 :         return 0;
     144                 :            :     }
     145                 :            : 
     146                 :         25 :     Py_DECREF(importer);
     147                 :         25 :     *importer_p = sys_path0;
     148                 :         25 :     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                 :       2215 : pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
     160                 :            : {
     161                 :            :     PyObject *sys_path;
     162                 :       2215 :     PyObject *sysdict = interp->sysdict;
     163         [ +  - ]:       2215 :     if (sysdict != NULL) {
     164                 :       2215 :         sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path));
     165   [ -  +  -  - ]:       2215 :         if (sys_path == NULL && PyErr_Occurred()) {
     166                 :          0 :             return -1;
     167                 :            :         }
     168                 :            :     }
     169                 :            :     else {
     170                 :          0 :         sys_path = NULL;
     171                 :            :     }
     172         [ -  + ]:       2215 :     if (sys_path == NULL) {
     173                 :          0 :         PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
     174                 :          0 :         return -1;
     175                 :            :     }
     176                 :            : 
     177         [ -  + ]:       2215 :     if (PyList_Insert(sys_path, 0, path0)) {
     178                 :          0 :         return -1;
     179                 :            :     }
     180                 :       2215 :     return 0;
     181                 :            : }
     182                 :            : 
     183                 :            : 
     184                 :            : static void
     185                 :       2881 : pymain_header(const PyConfig *config)
     186                 :            : {
     187         [ +  + ]:       2881 :     if (config->quiet) {
     188                 :          4 :         return;
     189                 :            :     }
     190                 :            : 
     191   [ +  +  +  +  :       2877 :     if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) {
                   +  + ]
     192                 :       2859 :         return;
     193                 :            :     }
     194                 :            : 
     195                 :         18 :     fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
     196         [ +  - ]:         18 :     if (config->site_import) {
     197                 :         18 :         fprintf(stderr, "%s\n", COPYRIGHT);
     198                 :            :     }
     199                 :            : }
     200                 :            : 
     201                 :            : 
     202                 :            : static void
     203                 :       2881 : pymain_import_readline(const PyConfig *config)
     204                 :            : {
     205         [ +  + ]:       2881 :     if (config->isolated) {
     206                 :        668 :         return;
     207                 :            :     }
     208   [ +  +  +  + ]:       2213 :     if (!config->inspect && config_run_code(config)) {
     209                 :       2193 :         return;
     210                 :            :     }
     211         [ +  + ]:         20 :     if (!isatty(fileno(stdin))) {
     212                 :         17 :         return;
     213                 :            :     }
     214                 :            : 
     215                 :          3 :     PyObject *mod = PyImport_ImportModule("readline");
     216         [ -  + ]:          3 :     if (mod == NULL) {
     217                 :          0 :         PyErr_Clear();
     218                 :            :     }
     219                 :            :     else {
     220                 :          3 :         Py_DECREF(mod);
     221                 :            :     }
     222                 :          3 :     mod = PyImport_ImportModule("rlcompleter");
     223         [ -  + ]:          3 :     if (mod == NULL) {
     224                 :          0 :         PyErr_Clear();
     225                 :            :     }
     226                 :            :     else {
     227                 :          3 :         Py_DECREF(mod);
     228                 :            :     }
     229                 :            : }
     230                 :            : 
     231                 :            : 
     232                 :            : static int
     233                 :       1616 : pymain_run_command(wchar_t *command)
     234                 :            : {
     235                 :            :     PyObject *unicode, *bytes;
     236                 :            :     int ret;
     237                 :            : 
     238                 :       1616 :     unicode = PyUnicode_FromWideChar(command, -1);
     239         [ -  + ]:       1616 :     if (unicode == NULL) {
     240                 :          0 :         goto error;
     241                 :            :     }
     242                 :            : 
     243         [ +  + ]:       1616 :     if (PySys_Audit("cpython.run_command", "O", unicode) < 0) {
     244                 :          1 :         return pymain_exit_err_print();
     245                 :            :     }
     246                 :            : 
     247                 :       1615 :     bytes = PyUnicode_AsUTF8String(unicode);
     248                 :       1615 :     Py_DECREF(unicode);
     249         [ +  + ]:       1615 :     if (bytes == NULL) {
     250                 :          1 :         goto error;
     251                 :            :     }
     252                 :            : 
     253                 :       1614 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
     254                 :       1614 :     cf.cf_flags |= PyCF_IGNORE_COOKIE;
     255                 :       1614 :     ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), &cf);
     256                 :        921 :     Py_DECREF(bytes);
     257                 :        921 :     return (ret != 0);
     258                 :            : 
     259                 :          1 : error:
     260                 :          1 :     PySys_WriteStderr("Unable to decode the command from the command line:\n");
     261                 :          1 :     return pymain_exit_err_print();
     262                 :            : }
     263                 :            : 
     264                 :            : 
     265                 :            : static int
     266                 :        898 : pymain_run_module(const wchar_t *modname, int set_argv0)
     267                 :            : {
     268                 :            :     PyObject *module, *runpy, *runmodule, *runargs, *result;
     269         [ -  + ]:        898 :     if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
     270                 :          0 :         return pymain_exit_err_print();
     271                 :            :     }
     272                 :        898 :     runpy = PyImport_ImportModule("runpy");
     273         [ -  + ]:        898 :     if (runpy == NULL) {
     274                 :          0 :         fprintf(stderr, "Could not import runpy module\n");
     275                 :          0 :         return pymain_exit_err_print();
     276                 :            :     }
     277                 :        898 :     runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
     278         [ -  + ]:        898 :     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                 :        898 :     module = PyUnicode_FromWideChar(modname, wcslen(modname));
     284         [ -  + ]:        898 :     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         [ +  + ]:        898 :     runargs = PyTuple_Pack(2, module, set_argv0 ? Py_True : Py_False);
     291         [ -  + ]:        898 :     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                 :        898 :     _Py_UnhandledKeyboardInterrupt = 0;
     300                 :        898 :     result = PyObject_Call(runmodule, runargs, NULL);
     301   [ +  +  -  + ]:        898 :     if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
     302                 :          0 :         _Py_UnhandledKeyboardInterrupt = 1;
     303                 :            :     }
     304                 :        898 :     Py_DECREF(runpy);
     305                 :        898 :     Py_DECREF(runmodule);
     306                 :        898 :     Py_DECREF(module);
     307                 :        898 :     Py_DECREF(runargs);
     308         [ +  + ]:        898 :     if (result == NULL) {
     309                 :        732 :         return pymain_exit_err_print();
     310                 :            :     }
     311                 :        166 :     Py_DECREF(result);
     312                 :        166 :     return 0;
     313                 :            : }
     314                 :            : 
     315                 :            : 
     316                 :            : static int
     317                 :        341 : pymain_run_file_obj(PyObject *program_name, PyObject *filename,
     318                 :            :                     int skip_source_first_line)
     319                 :            : {
     320         [ +  + ]:        341 :     if (PySys_Audit("cpython.run_file", "O", filename) < 0) {
     321                 :          1 :         return pymain_exit_err_print();
     322                 :            :     }
     323                 :            : 
     324                 :        340 :     FILE *fp = _Py_fopen_obj(filename, "rb");
     325         [ +  + ]:        340 :     if (fp == NULL) {
     326                 :            :         // Ignore the OSError
     327                 :          2 :         PyErr_Clear();
     328                 :          4 :         PySys_FormatStderr("%S: can't open file %R: [Errno %d] %s\n",
     329                 :          2 :                            program_name, filename, errno, strerror(errno));
     330                 :          2 :         return 2;
     331                 :            :     }
     332                 :            : 
     333         [ -  + ]:        338 :     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   [ +  -  -  + ]:        338 :     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         [ -  + ]:        338 :     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                 :        338 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
     360                 :        338 :     int run = _PyRun_AnyFileObject(fp, filename, 1, &cf);
     361                 :        291 :     return (run != 0);
     362                 :            : }
     363                 :            : 
     364                 :            : static int
     365                 :        341 : pymain_run_file(const PyConfig *config)
     366                 :            : {
     367                 :        341 :     PyObject *filename = PyUnicode_FromWideChar(config->run_filename, -1);
     368         [ -  + ]:        341 :     if (filename == NULL) {
     369                 :          0 :         PyErr_Print();
     370                 :          0 :         return -1;
     371                 :            :     }
     372                 :        341 :     PyObject *program_name = PyUnicode_FromWideChar(config->program_name, -1);
     373         [ -  + ]:        341 :     if (program_name == NULL) {
     374                 :          0 :         Py_DECREF(filename);
     375                 :          0 :         PyErr_Print();
     376                 :          0 :         return -1;
     377                 :            :     }
     378                 :            : 
     379                 :        341 :     int res = pymain_run_file_obj(program_name, filename,
     380                 :        341 :                                   config->skip_source_first_line);
     381                 :        294 :     Py_DECREF(filename);
     382                 :        294 :     Py_DECREF(program_name);
     383                 :        294 :     return res;
     384                 :            : }
     385                 :            : 
     386                 :            : 
     387                 :            : static int
     388                 :         13 : pymain_run_startup(PyConfig *config, int *exitcode)
     389                 :            : {
     390                 :            :     int ret;
     391         [ +  + ]:         13 :     if (!config->use_environment) {
     392                 :          7 :         return 0;
     393                 :            :     }
     394                 :          6 :     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                 :          6 :     const char *env = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
     406         [ -  + ]:          6 :     if (env == NULL) {
     407                 :          0 :         return 0;
     408                 :            :     }
     409                 :          6 :     startup = PyUnicode_DecodeFSDefault(env);
     410         [ -  + ]:          6 :     if (startup == NULL) {
     411                 :          0 :         goto error;
     412                 :            :     }
     413                 :            : #endif
     414         [ -  + ]:          6 :     if (PySys_Audit("cpython.run_startup", "O", startup) < 0) {
     415                 :          0 :         goto error;
     416                 :            :     }
     417                 :            : 
     418                 :          5 :     FILE *fp = _Py_fopen_obj(startup, "r");
     419         [ -  + ]:          5 :     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                 :          5 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
     430                 :          5 :     (void) _PyRun_SimpleFileObject(fp, startup, 0, &cf);
     431                 :          5 :     PyErr_Clear();
     432                 :          5 :     fclose(fp);
     433                 :          5 :     ret = 0;
     434                 :            : 
     435                 :          5 : done:
     436                 :          5 :     Py_XDECREF(startup);
     437                 :          5 :     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                 :         14 : pymain_run_interactive_hook(int *exitcode)
     449                 :            : {
     450                 :            :     PyObject *sys, *hook, *result;
     451                 :         14 :     sys = PyImport_ImportModule("sys");
     452         [ -  + ]:         14 :     if (sys == NULL) {
     453                 :          0 :         goto error;
     454                 :            :     }
     455                 :            : 
     456                 :         14 :     hook = PyObject_GetAttrString(sys, "__interactivehook__");
     457                 :         14 :     Py_DECREF(sys);
     458         [ -  + ]:         14 :     if (hook == NULL) {
     459                 :          0 :         PyErr_Clear();
     460                 :          0 :         return 0;
     461                 :            :     }
     462                 :            : 
     463         [ -  + ]:         14 :     if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
     464                 :          0 :         goto error;
     465                 :            :     }
     466                 :            : 
     467                 :         13 :     result = _PyObject_CallNoArgs(hook);
     468                 :         13 :     Py_DECREF(hook);
     469         [ -  + ]:         13 :     if (result == NULL) {
     470                 :          0 :         goto error;
     471                 :            :     }
     472                 :         13 :     Py_DECREF(result);
     473                 :            : 
     474                 :         13 :     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                 :         15 : pymain_set_inspect(PyConfig *config, int inspect)
     484                 :            : {
     485                 :         15 :     config->inspect = inspect;
     486                 :            : _Py_COMP_DIAG_PUSH
     487                 :            : _Py_COMP_DIAG_IGNORE_DEPR_DECLS
     488                 :         15 :     Py_InspectFlag = inspect;
     489                 :            : _Py_COMP_DIAG_POP
     490                 :         15 : }
     491                 :            : 
     492                 :            : 
     493                 :            : static int
     494                 :         26 : pymain_run_stdin(PyConfig *config)
     495                 :            : {
     496         [ +  + ]:         26 :     if (stdin_is_interactive(config)) {
     497                 :            :         // do exit on SystemExit
     498                 :         13 :         pymain_set_inspect(config, 0);
     499                 :            : 
     500                 :            :         int exitcode;
     501         [ -  + ]:         13 :         if (pymain_run_startup(config, &exitcode)) {
     502                 :          0 :             return exitcode;
     503                 :            :         }
     504                 :            : 
     505         [ -  + ]:         12 :         if (pymain_run_interactive_hook(&exitcode)) {
     506                 :          0 :             return exitcode;
     507                 :            :         }
     508                 :            :     }
     509                 :            : 
     510                 :            :     /* call pending calls like signal handlers (SIGINT) */
     511         [ -  + ]:         24 :     if (Py_MakePendingCalls() == -1) {
     512                 :          0 :         return pymain_exit_err_print();
     513                 :            :     }
     514                 :            : 
     515         [ +  + ]:         24 :     if (PySys_Audit("cpython.run_stdin", NULL) < 0) {
     516                 :          1 :         return pymain_exit_err_print();
     517                 :            :     }
     518                 :            : 
     519                 :         23 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
     520                 :         23 :     int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
     521                 :         20 :     return (run != 0);
     522                 :            : }
     523                 :            : 
     524                 :            : 
     525                 :            : static void
     526                 :       2136 : 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   [ +  +  -  + ]:       2136 :     if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
     531                 :          0 :         pymain_set_inspect(config, 1);
     532                 :            :     }
     533                 :            : 
     534   [ +  +  +  -  :       2136 :     if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
                   -  + ]
     535                 :       2134 :         return;
     536                 :            :     }
     537                 :            : 
     538                 :          2 :     pymain_set_inspect(config, 0);
     539         [ -  + ]:          2 :     if (pymain_run_interactive_hook(exitcode)) {
     540                 :          0 :         return;
     541                 :            :     }
     542                 :            : 
     543                 :          2 :     PyCompilerFlags cf = _PyCompilerFlags_INIT;
     544                 :          2 :     int res = PyRun_AnyFileFlags(stdin, "<stdin>", &cf);
     545                 :          1 :     *exitcode = (res != 0);
     546                 :            : }
     547                 :            : 
     548                 :            : 
     549                 :            : static void
     550                 :       2881 : pymain_run_python(int *exitcode)
     551                 :            : {
     552                 :       2881 :     PyObject *main_importer_path = NULL;
     553                 :       2881 :     PyInterpreterState *interp = _PyInterpreterState_GET();
     554                 :            :     /* pymain_run_stdin() modify the config */
     555                 :       2881 :     PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
     556                 :            : 
     557                 :            :     /* ensure path config is written into global variables */
     558         [ -  + ]:       2881 :     if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) {
     559                 :          0 :         goto error;
     560                 :            :     }
     561                 :            : 
     562         [ +  + ]:       2881 :     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         [ -  + ]:        366 :         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                 :       2881 :     pymain_import_readline(config);
     576                 :            : 
     577         [ +  + ]:       2881 :     if (main_importer_path != NULL) {
     578         [ -  + ]:         25 :         if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
     579                 :          0 :             goto error;
     580                 :            :         }
     581                 :            :     }
     582         [ +  + ]:       2856 :     else if (!config->safe_path) {
     583                 :       2190 :         PyObject *path0 = NULL;
     584                 :       2190 :         int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
     585         [ -  + ]:       2190 :         if (res < 0) {
     586                 :          0 :             goto error;
     587                 :            :         }
     588                 :            : 
     589         [ +  - ]:       2190 :         if (res > 0) {
     590         [ -  + ]:       2190 :             if (pymain_sys_path_add_path0(interp, path0) < 0) {
     591                 :          0 :                 Py_DECREF(path0);
     592                 :          0 :                 goto error;
     593                 :            :             }
     594                 :       2190 :             Py_DECREF(path0);
     595                 :            :         }
     596                 :            :     }
     597                 :            : 
     598                 :       2881 :     pymain_header(config);
     599                 :            : 
     600         [ +  + ]:       2881 :     if (config->run_command) {
     601                 :       1616 :         *exitcode = pymain_run_command(config->run_command);
     602                 :            :     }
     603         [ +  + ]:       1265 :     else if (config->run_module) {
     604                 :        873 :         *exitcode = pymain_run_module(config->run_module, 1);
     605                 :            :     }
     606         [ +  + ]:        392 :     else if (main_importer_path != NULL) {
     607                 :         25 :         *exitcode = pymain_run_module(L"__main__", 0);
     608                 :            :     }
     609         [ +  + ]:        367 :     else if (config->run_filename != NULL) {
     610                 :        341 :         *exitcode = pymain_run_file(config);
     611                 :            :     }
     612                 :            :     else {
     613                 :         26 :         *exitcode = pymain_run_stdin(config);
     614                 :            :     }
     615                 :            : 
     616                 :       2136 :     pymain_repl(config, exitcode);
     617                 :       2135 :     goto done;
     618                 :            : 
     619                 :          0 : error:
     620                 :          0 :     *exitcode = pymain_exit_err_print();
     621                 :            : 
     622                 :       2135 : done:
     623                 :       2135 :     Py_XDECREF(main_importer_path);
     624                 :            : }
     625                 :            : 
     626                 :            : 
     627                 :            : /* --- pymain_main() ---------------------------------------------- */
     628                 :            : 
     629                 :            : static void
     630                 :       2152 : pymain_free(void)
     631                 :            : {
     632                 :       2152 :     _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                 :       2152 :     _PyPathConfig_ClearGlobal();
     639                 :       2152 :     _Py_ClearStandardStreamEncoding();
     640                 :       2152 :     _Py_ClearArgcArgv();
     641                 :       2152 :     _PyRuntime_Finalize();
     642                 :       2152 : }
     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(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                 :          6 : pymain_exit_error(PyStatus status)
     673                 :            : {
     674         [ -  + ]:          6 :     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                 :          6 :     Py_ExitStatusException(status);
     681                 :            : }
     682                 :            : 
     683                 :            : 
     684                 :            : int
     685                 :       2881 : Py_RunMain(void)
     686                 :            : {
     687                 :       2881 :     int exitcode = 0;
     688                 :            : 
     689                 :       2881 :     pymain_run_python(&exitcode);
     690                 :            : 
     691         [ +  + ]:       2135 :     if (Py_FinalizeEx() < 0) {
     692                 :            :         /* Value unlikely to be confused with a non-error exit status or
     693                 :            :            other special meaning */
     694                 :          1 :         exitcode = 120;
     695                 :            :     }
     696                 :            : 
     697                 :       2135 :     pymain_free();
     698                 :            : 
     699         [ -  + ]:       2135 :     if (_Py_UnhandledKeyboardInterrupt) {
     700                 :          0 :         exitcode = exit_sigint();
     701                 :            :     }
     702                 :            : 
     703                 :       2135 :     return exitcode;
     704                 :            : }
     705                 :            : 
     706                 :            : 
     707                 :            : static int
     708                 :       2868 : pymain_main(_PyArgv *args)
     709                 :            : {
     710                 :       2868 :     PyStatus status = pymain_init(args);
     711         [ +  + ]:       2868 :     if (_PyStatus_IS_EXIT(status)) {
     712                 :         17 :         pymain_free();
     713                 :         17 :         return status.exitcode;
     714                 :            :     }
     715         [ +  + ]:       2851 :     if (_PyStatus_EXCEPTION(status)) {
     716                 :          6 :         pymain_exit_error(status);
     717                 :            :     }
     718                 :            : 
     719                 :       2845 :     return Py_RunMain();
     720                 :            : }
     721                 :            : 
     722                 :            : 
     723                 :            : int
     724                 :          3 : Py_Main(int argc, wchar_t **argv)
     725                 :            : {
     726                 :          3 :     _PyArgv args = {
     727                 :            :         .argc = argc,
     728                 :            :         .use_bytes_argv = 0,
     729                 :            :         .bytes_argv = NULL,
     730                 :            :         .wchar_argv = argv};
     731                 :          3 :     return pymain_main(&args);
     732                 :            : }
     733                 :            : 
     734                 :            : 
     735                 :            : int
     736                 :       2865 : Py_BytesMain(int argc, char **argv)
     737                 :            : {
     738                 :       2865 :     _PyArgv args = {
     739                 :            :         .argc = argc,
     740                 :            :         .use_bytes_argv = 1,
     741                 :            :         .bytes_argv = argv,
     742                 :            :         .wchar_argv = NULL};
     743                 :       2865 :     return pymain_main(&args);
     744                 :            : }
     745                 :            : 
     746                 :            : #ifdef __cplusplus
     747                 :            : }
     748                 :            : #endif

Generated by: LCOV version 1.14