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