main.c 19 KB

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