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