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 2864 : pymain_init(const _PyArgv *args)
36 : {
37 : PyStatus status;
38 :
39 2864 : status = _PyRuntime_Initialize();
40 2864 : if (_PyStatus_EXCEPTION(status)) {
41 0 : return status;
42 : }
43 :
44 : PyPreConfig preconfig;
45 2864 : PyPreConfig_InitPythonConfig(&preconfig);
46 :
47 2864 : status = _Py_PreInitializeFromPyArgv(&preconfig, args);
48 2864 : if (_PyStatus_EXCEPTION(status)) {
49 1 : return status;
50 : }
51 :
52 : PyConfig config;
53 2863 : PyConfig_InitPythonConfig(&config);
54 :
55 : /* pass NULL as the config: config is read from command line arguments,
56 : environment variables, configuration files */
57 2863 : if (args->use_bytes_argv) {
58 2860 : 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 2863 : if (_PyStatus_EXCEPTION(status)) {
64 0 : goto done;
65 : }
66 :
67 2863 : status = Py_InitializeFromConfig(&config);
68 2863 : if (_PyStatus_EXCEPTION(status)) {
69 22 : goto done;
70 : }
71 2841 : status = _PyStatus_OK();
72 :
73 2863 : done:
74 2863 : PyConfig_Clear(&config);
75 2863 : 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 5032 : static inline int config_run_code(const PyConfig *config)
84 : {
85 5032 : return (config->run_command != NULL
86 2125 : || config->run_filename != NULL
87 7157 : || 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 738 : pymain_err_print(int *exitcode_p)
102 : {
103 : int exitcode;
104 738 : if (_Py_HandleSystemExit(&exitcode)) {
105 714 : *exitcode_p = exitcode;
106 714 : return 1;
107 : }
108 :
109 24 : PyErr_Print();
110 24 : return 0;
111 : }
112 :
113 :
114 : static int
115 738 : pymain_exit_err_print(void)
116 : {
117 738 : int exitcode = 1;
118 738 : pymain_err_print(&exitcode);
119 738 : 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 2179 : pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
160 : {
161 : PyObject *sys_path;
162 2179 : PyObject *sysdict = interp->sysdict;
163 2179 : if (sysdict != NULL) {
164 2179 : sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path));
165 2179 : if (sys_path == NULL && PyErr_Occurred()) {
166 0 : return -1;
167 : }
168 : }
169 : else {
170 0 : sys_path = NULL;
171 : }
172 2179 : if (sys_path == NULL) {
173 0 : PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
174 0 : return -1;
175 : }
176 :
177 2179 : if (PyList_Insert(sys_path, 0, path0)) {
178 0 : return -1;
179 : }
180 2179 : return 0;
181 : }
182 :
183 :
184 : static void
185 2877 : pymain_header(const PyConfig *config)
186 : {
187 2877 : if (config->quiet) {
188 4 : return;
189 : }
190 :
191 2873 : if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) {
192 2855 : 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 2877 : pymain_import_readline(const PyConfig *config)
204 : {
205 2877 : if (config->isolated) {
206 700 : return;
207 : }
208 2177 : if (!config->inspect && config_run_code(config)) {
209 2157 : return;
210 : }
211 20 : if (!isatty(fileno(stdin))) {
212 20 : return;
213 : }
214 :
215 0 : PyObject *mod = PyImport_ImportModule("readline");
216 0 : if (mod == NULL) {
217 0 : PyErr_Clear();
218 : }
219 : else {
220 0 : Py_DECREF(mod);
221 : }
222 0 : mod = PyImport_ImportModule("rlcompleter");
223 0 : if (mod == NULL) {
224 0 : PyErr_Clear();
225 : }
226 : else {
227 0 : Py_DECREF(mod);
228 : }
229 : }
230 :
231 :
232 : static int
233 1611 : pymain_run_command(wchar_t *command)
234 : {
235 : PyObject *unicode, *bytes;
236 : int ret;
237 :
238 1611 : unicode = PyUnicode_FromWideChar(command, -1);
239 1611 : if (unicode == NULL) {
240 0 : goto error;
241 : }
242 :
243 1611 : if (PySys_Audit("cpython.run_command", "O", unicode) < 0) {
244 1 : return pymain_exit_err_print();
245 : }
246 :
247 1610 : bytes = PyUnicode_AsUTF8String(unicode);
248 1610 : Py_DECREF(unicode);
249 1610 : if (bytes == NULL) {
250 1 : goto error;
251 : }
252 :
253 1609 : PyCompilerFlags cf = _PyCompilerFlags_INIT;
254 1609 : cf.cf_flags |= PyCF_IGNORE_COOKIE;
255 1609 : ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), &cf);
256 935 : Py_DECREF(bytes);
257 935 : 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 899 : pymain_run_module(const wchar_t *modname, int set_argv0)
267 : {
268 : PyObject *module, *runpy, *runmodule, *runargs, *result;
269 899 : if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
270 0 : return pymain_exit_err_print();
271 : }
272 899 : runpy = PyImport_ImportModule("runpy");
273 899 : if (runpy == NULL) {
274 0 : fprintf(stderr, "Could not import runpy module\n");
275 0 : return pymain_exit_err_print();
276 : }
277 899 : runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
278 899 : 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 899 : module = PyUnicode_FromWideChar(modname, wcslen(modname));
284 899 : 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 899 : runargs = PyTuple_Pack(2, module, set_argv0 ? Py_True : Py_False);
291 899 : 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 899 : _Py_UnhandledKeyboardInterrupt = 0;
300 899 : result = PyObject_Call(runmodule, runargs, NULL);
301 899 : if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
302 0 : _Py_UnhandledKeyboardInterrupt = 1;
303 : }
304 899 : Py_DECREF(runpy);
305 899 : Py_DECREF(runmodule);
306 899 : Py_DECREF(module);
307 899 : Py_DECREF(runargs);
308 899 : if (result == NULL) {
309 734 : return pymain_exit_err_print();
310 : }
311 165 : Py_DECREF(result);
312 165 : 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 : 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 4 : return 0;
408 : }
409 2 : startup = PyUnicode_DecodeFSDefault(env);
410 2 : if (startup == NULL) {
411 0 : goto error;
412 : }
413 : #endif
414 2 : if (PySys_Audit("cpython.run_startup", "O", startup) < 0) {
415 0 : goto error;
416 : }
417 :
418 1 : FILE *fp = _Py_fopen_obj(startup, "r");
419 1 : 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 1 : PyCompilerFlags cf = _PyCompilerFlags_INIT;
430 1 : (void) _PyRun_SimpleFileObject(fp, startup, 0, &cf);
431 1 : PyErr_Clear();
432 1 : fclose(fp);
433 1 : ret = 0;
434 :
435 1 : done:
436 1 : Py_XDECREF(startup);
437 1 : 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 2151 : 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 2151 : if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
531 0 : pymain_set_inspect(config, 1);
532 : }
533 :
534 2151 : if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
535 2149 : 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 2877 : pymain_run_python(int *exitcode)
551 : {
552 2877 : PyObject *main_importer_path = NULL;
553 2877 : PyInterpreterState *interp = _PyInterpreterState_GET();
554 : /* pymain_run_stdin() modify the config */
555 2877 : PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
556 :
557 : /* ensure path config is written into global variables */
558 2877 : if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) {
559 0 : goto error;
560 : }
561 :
562 2877 : 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 2877 : pymain_import_readline(config);
576 :
577 2877 : 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 2852 : else if (!config->safe_path) {
583 2154 : PyObject *path0 = NULL;
584 2154 : int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
585 2154 : if (res < 0) {
586 0 : goto error;
587 : }
588 :
589 2154 : if (res > 0) {
590 2154 : if (pymain_sys_path_add_path0(interp, path0) < 0) {
591 0 : Py_DECREF(path0);
592 0 : goto error;
593 : }
594 2154 : Py_DECREF(path0);
595 : }
596 : }
597 :
598 2877 : pymain_header(config);
599 :
600 2877 : if (config->run_command) {
601 1611 : *exitcode = pymain_run_command(config->run_command);
602 : }
603 1266 : else if (config->run_module) {
604 874 : *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 2151 : pymain_repl(config, exitcode);
617 2150 : goto done;
618 :
619 0 : error:
620 0 : *exitcode = pymain_exit_err_print();
621 :
622 2150 : done:
623 2150 : Py_XDECREF(main_importer_path);
624 : }
625 :
626 :
627 : /* --- pymain_main() ---------------------------------------------- */
628 :
629 : static void
630 2167 : pymain_free(void)
631 : {
632 2167 : _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 2167 : _PyPathConfig_ClearGlobal();
639 2167 : _Py_ClearStandardStreamEncoding();
640 2167 : _Py_ClearArgcArgv();
641 2167 : _PyRuntime_Finalize();
642 2167 : }
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 2877 : Py_RunMain(void)
686 : {
687 2877 : int exitcode = 0;
688 :
689 2877 : pymain_run_python(&exitcode);
690 :
691 2150 : 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 2150 : pymain_free();
698 :
699 2150 : if (_Py_UnhandledKeyboardInterrupt) {
700 0 : exitcode = exit_sigint();
701 : }
702 :
703 2150 : return exitcode;
704 : }
705 :
706 :
707 : static int
708 2864 : pymain_main(_PyArgv *args)
709 : {
710 2864 : PyStatus status = pymain_init(args);
711 2864 : if (_PyStatus_IS_EXIT(status)) {
712 17 : pymain_free();
713 17 : return status.exitcode;
714 : }
715 2847 : if (_PyStatus_EXCEPTION(status)) {
716 6 : pymain_exit_error(status);
717 : }
718 :
719 2841 : 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 2861 : Py_BytesMain(int argc, char **argv)
737 : {
738 2861 : _PyArgv args = {
739 : .argc = argc,
740 : .use_bytes_argv = 1,
741 : .bytes_argv = argv,
742 : .wchar_argv = NULL};
743 2861 : return pymain_main(&args);
744 : }
745 :
746 : #ifdef __cplusplus
747 : }
748 : #endif
|