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
28 extern "C" {
29 #endif
30
31 /* --- pymain_init() ---------------------------------------------- */
32
33 static PyStatus
pymain_init(const _PyArgv * args)34 pymain_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
72 done:
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 */
config_run_code(const PyConfig * config)82 static 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 is stdin is a TTY or if -i command line option is used */
91 static int
stdin_is_interactive(const PyConfig * config)92 stdin_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 */
99 static int
pymain_err_print(int * exitcode_p)100 pymain_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
113 static int
pymain_exit_err_print(void)114 pymain_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. */
124 static int
pymain_get_importer(const wchar_t * filename,PyObject ** importer_p,int * exitcode)125 pymain_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
149 error:
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
157 static int
pymain_sys_path_add_path0(PyInterpreterState * interp,PyObject * path0)158 pymain_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
184 static void
pymain_header(const PyConfig * config)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
pymain_import_readline(const PyConfig * config)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 }
223
224
225 static int
pymain_run_command(wchar_t * command,PyCompilerFlags * cf)226 pymain_run_command(wchar_t *command, PyCompilerFlags *cf)
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 ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf);
247 Py_DECREF(bytes);
248 return (ret != 0);
249
250 error:
251 PySys_WriteStderr("Unable to decode the command from the command line:\n");
252 return pymain_exit_err_print();
253 }
254
255
256 static int
pymain_run_module(const wchar_t * modname,int set_argv0)257 pymain_run_module(const wchar_t *modname, int set_argv0)
258 {
259 PyObject *module, *runpy, *runmodule, *runargs, *result;
260 if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
261 return pymain_exit_err_print();
262 }
263 runpy = PyImport_ImportModule("runpy");
264 if (runpy == NULL) {
265 fprintf(stderr, "Could not import runpy module\n");
266 return pymain_exit_err_print();
267 }
268 runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
269 if (runmodule == NULL) {
270 fprintf(stderr, "Could not access runpy._run_module_as_main\n");
271 Py_DECREF(runpy);
272 return pymain_exit_err_print();
273 }
274 module = PyUnicode_FromWideChar(modname, wcslen(modname));
275 if (module == NULL) {
276 fprintf(stderr, "Could not convert module name to unicode\n");
277 Py_DECREF(runpy);
278 Py_DECREF(runmodule);
279 return pymain_exit_err_print();
280 }
281 runargs = PyTuple_Pack(2, module, set_argv0 ? Py_True : Py_False);
282 if (runargs == NULL) {
283 fprintf(stderr,
284 "Could not create arguments for runpy._run_module_as_main\n");
285 Py_DECREF(runpy);
286 Py_DECREF(runmodule);
287 Py_DECREF(module);
288 return pymain_exit_err_print();
289 }
290 _Py_UnhandledKeyboardInterrupt = 0;
291 result = PyObject_Call(runmodule, runargs, NULL);
292 if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
293 _Py_UnhandledKeyboardInterrupt = 1;
294 }
295 Py_DECREF(runpy);
296 Py_DECREF(runmodule);
297 Py_DECREF(module);
298 Py_DECREF(runargs);
299 if (result == NULL) {
300 return pymain_exit_err_print();
301 }
302 Py_DECREF(result);
303 return 0;
304 }
305
306
307 static int
pymain_run_file(const PyConfig * config,PyCompilerFlags * cf)308 pymain_run_file(const PyConfig *config, PyCompilerFlags *cf)
309 {
310 const wchar_t *filename = config->run_filename;
311 if (PySys_Audit("cpython.run_file", "u", filename) < 0) {
312 return pymain_exit_err_print();
313 }
314 FILE *fp = _Py_wfopen(filename, L"rb");
315 if (fp == NULL) {
316 char *cfilename_buffer;
317 const char *cfilename;
318 int err = errno;
319 cfilename_buffer = _Py_EncodeLocaleRaw(filename, NULL);
320 if (cfilename_buffer != NULL)
321 cfilename = cfilename_buffer;
322 else
323 cfilename = "<unprintable file name>";
324 fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
325 config->program_name, cfilename, err, strerror(err));
326 PyMem_RawFree(cfilename_buffer);
327 return 2;
328 }
329
330 if (config->skip_source_first_line) {
331 int ch;
332 /* Push back first newline so line numbers remain the same */
333 while ((ch = getc(fp)) != EOF) {
334 if (ch == '\n') {
335 (void)ungetc(ch, fp);
336 break;
337 }
338 }
339 }
340
341 struct _Py_stat_struct sb;
342 if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) {
343 fprintf(stderr,
344 "%ls: '%ls' is a directory, cannot continue\n",
345 config->program_name, filename);
346 fclose(fp);
347 return 1;
348 }
349
350 /* call pending calls like signal handlers (SIGINT) */
351 if (Py_MakePendingCalls() == -1) {
352 fclose(fp);
353 return pymain_exit_err_print();
354 }
355
356 PyObject *unicode, *bytes = NULL;
357 const char *filename_str;
358
359 unicode = PyUnicode_FromWideChar(filename, wcslen(filename));
360 if (unicode != NULL) {
361 bytes = PyUnicode_EncodeFSDefault(unicode);
362 Py_DECREF(unicode);
363 }
364 if (bytes != NULL) {
365 filename_str = PyBytes_AsString(bytes);
366 }
367 else {
368 PyErr_Clear();
369 filename_str = "<filename encoding error>";
370 }
371
372 /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */
373 int run = PyRun_AnyFileExFlags(fp, filename_str, 1, cf);
374 Py_XDECREF(bytes);
375 return (run != 0);
376 }
377
378
379 static int
pymain_run_startup(PyConfig * config,PyCompilerFlags * cf,int * exitcode)380 pymain_run_startup(PyConfig *config, PyCompilerFlags *cf, int *exitcode)
381 {
382 int ret;
383 PyObject *startup_obj = NULL;
384 if (!config->use_environment) {
385 return 0;
386 }
387 #ifdef MS_WINDOWS
388 const wchar_t *wstartup = _wgetenv(L"PYTHONSTARTUP");
389 if (wstartup == NULL || wstartup[0] == L'\0') {
390 return 0;
391 }
392 PyObject *startup_bytes = NULL;
393 startup_obj = PyUnicode_FromWideChar(wstartup, wcslen(wstartup));
394 if (startup_obj == NULL) {
395 goto error;
396 }
397 startup_bytes = PyUnicode_EncodeFSDefault(startup_obj);
398 if (startup_bytes == NULL) {
399 goto error;
400 }
401 const char *startup = PyBytes_AS_STRING(startup_bytes);
402 #else
403 const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
404 if (startup == NULL) {
405 return 0;
406 }
407 startup_obj = PyUnicode_DecodeFSDefault(startup);
408 if (startup_obj == NULL) {
409 goto error;
410 }
411 #endif
412 if (PySys_Audit("cpython.run_startup", "O", startup_obj) < 0) {
413 goto error;
414 }
415
416 #ifdef MS_WINDOWS
417 FILE *fp = _Py_wfopen(wstartup, L"r");
418 #else
419 FILE *fp = _Py_fopen(startup, "r");
420 #endif
421 if (fp == NULL) {
422 int save_errno = errno;
423 PyErr_Clear();
424 PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
425
426 errno = save_errno;
427 PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, startup_obj, NULL);
428 goto error;
429 }
430
431 (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
432 PyErr_Clear();
433 fclose(fp);
434 ret = 0;
435
436 done:
437 #ifdef MS_WINDOWS
438 Py_XDECREF(startup_bytes);
439 #endif
440 Py_XDECREF(startup_obj);
441 return ret;
442
443 error:
444 ret = pymain_err_print(exitcode);
445 goto done;
446 }
447
448
449 /* Write an exitcode into *exitcode and return 1 if we have to exit Python.
450 Return 0 otherwise. */
451 static int
pymain_run_interactive_hook(int * exitcode)452 pymain_run_interactive_hook(int *exitcode)
453 {
454 PyObject *sys, *hook, *result;
455 sys = PyImport_ImportModule("sys");
456 if (sys == NULL) {
457 goto error;
458 }
459
460 hook = PyObject_GetAttrString(sys, "__interactivehook__");
461 Py_DECREF(sys);
462 if (hook == NULL) {
463 PyErr_Clear();
464 return 0;
465 }
466
467 if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
468 goto error;
469 }
470
471 result = _PyObject_CallNoArg(hook);
472 Py_DECREF(hook);
473 if (result == NULL) {
474 goto error;
475 }
476 Py_DECREF(result);
477
478 return 0;
479
480 error:
481 PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
482 return pymain_err_print(exitcode);
483 }
484
485
486 static int
pymain_run_stdin(PyConfig * config,PyCompilerFlags * cf)487 pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf)
488 {
489 if (stdin_is_interactive(config)) {
490 config->inspect = 0;
491 Py_InspectFlag = 0; /* do exit on SystemExit */
492
493 int exitcode;
494 if (pymain_run_startup(config, cf, &exitcode)) {
495 return exitcode;
496 }
497
498 if (pymain_run_interactive_hook(&exitcode)) {
499 return exitcode;
500 }
501 }
502
503 /* call pending calls like signal handlers (SIGINT) */
504 if (Py_MakePendingCalls() == -1) {
505 return pymain_exit_err_print();
506 }
507
508 if (PySys_Audit("cpython.run_stdin", NULL) < 0) {
509 return pymain_exit_err_print();
510 }
511
512 int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, cf);
513 return (run != 0);
514 }
515
516
517 static void
pymain_repl(PyConfig * config,PyCompilerFlags * cf,int * exitcode)518 pymain_repl(PyConfig *config, PyCompilerFlags *cf, int *exitcode)
519 {
520 /* Check this environment variable at the end, to give programs the
521 opportunity to set it from Python. */
522 if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
523 config->inspect = 1;
524 Py_InspectFlag = 1;
525 }
526
527 if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
528 return;
529 }
530
531 config->inspect = 0;
532 Py_InspectFlag = 0;
533 if (pymain_run_interactive_hook(exitcode)) {
534 return;
535 }
536
537 int res = PyRun_AnyFileFlags(stdin, "<stdin>", cf);
538 *exitcode = (res != 0);
539 }
540
541
542 static void
pymain_run_python(int * exitcode)543 pymain_run_python(int *exitcode)
544 {
545 PyInterpreterState *interp = _PyInterpreterState_GET();
546 /* pymain_run_stdin() modify the config */
547 PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
548
549 PyObject *main_importer_path = NULL;
550 if (config->run_filename != NULL) {
551 /* If filename is a package (ex: directory or ZIP file) which contains
552 __main__.py, main_importer_path is set to filename and will be
553 prepended to sys.path.
554
555 Otherwise, main_importer_path is left unchanged. */
556 if (pymain_get_importer(config->run_filename, &main_importer_path,
557 exitcode)) {
558 return;
559 }
560 }
561
562 if (main_importer_path != NULL) {
563 if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
564 goto error;
565 }
566 }
567 else if (!config->isolated) {
568 PyObject *path0 = NULL;
569 int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
570 if (res < 0) {
571 goto error;
572 }
573
574 if (res > 0) {
575 if (pymain_sys_path_add_path0(interp, path0) < 0) {
576 Py_DECREF(path0);
577 goto error;
578 }
579 Py_DECREF(path0);
580 }
581 }
582
583 PyCompilerFlags cf = _PyCompilerFlags_INIT;
584
585 pymain_header(config);
586 pymain_import_readline(config);
587
588 if (config->run_command) {
589 *exitcode = pymain_run_command(config->run_command, &cf);
590 }
591 else if (config->run_module) {
592 *exitcode = pymain_run_module(config->run_module, 1);
593 }
594 else if (main_importer_path != NULL) {
595 *exitcode = pymain_run_module(L"__main__", 0);
596 }
597 else if (config->run_filename != NULL) {
598 *exitcode = pymain_run_file(config, &cf);
599 }
600 else {
601 *exitcode = pymain_run_stdin(config, &cf);
602 }
603
604 pymain_repl(config, &cf, exitcode);
605 goto done;
606
607 error:
608 *exitcode = pymain_exit_err_print();
609
610 done:
611 Py_XDECREF(main_importer_path);
612 }
613
614
615 /* --- pymain_main() ---------------------------------------------- */
616
617 static void
pymain_free(void)618 pymain_free(void)
619 {
620 _PyImport_Fini2();
621
622 /* Free global variables which cannot be freed in Py_Finalize():
623 configuration options set before Py_Initialize() which should
624 remain valid after Py_Finalize(), since
625 Py_Initialize()-Py_Finalize() can be called multiple times. */
626 _PyPathConfig_ClearGlobal();
627 _Py_ClearStandardStreamEncoding();
628 _Py_ClearArgcArgv();
629 _PyRuntime_Finalize();
630 }
631
632
633 static int
exit_sigint(void)634 exit_sigint(void)
635 {
636 /* bpo-1054041: We need to exit via the
637 * SIG_DFL handler for SIGINT if KeyboardInterrupt went unhandled.
638 * If we don't, a calling process such as a shell may not know
639 * about the user's ^C. https://www.cons.org/cracauer/sigint.html */
640 #if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
641 if (PyOS_setsig(SIGINT, SIG_DFL) == SIG_ERR) {
642 perror("signal"); /* Impossible in normal environments. */
643 } else {
644 kill(getpid(), SIGINT);
645 }
646 /* If setting SIG_DFL failed, or kill failed to terminate us,
647 * there isn't much else we can do aside from an error code. */
648 #endif /* HAVE_GETPID && !MS_WINDOWS */
649 #ifdef MS_WINDOWS
650 /* cmd.exe detects this, prints ^C, and offers to terminate. */
651 /* https://msdn.microsoft.com/en-us/library/cc704588.aspx */
652 return STATUS_CONTROL_C_EXIT;
653 #else
654 return SIGINT + 128;
655 #endif /* !MS_WINDOWS */
656 }
657
658
659 static void _Py_NO_RETURN
pymain_exit_error(PyStatus status)660 pymain_exit_error(PyStatus status)
661 {
662 if (_PyStatus_IS_EXIT(status)) {
663 /* If it's an error rather than a regular exit, leave Python runtime
664 alive: Py_ExitStatusException() uses the current exception and use
665 sys.stdout in this case. */
666 pymain_free();
667 }
668 Py_ExitStatusException(status);
669 }
670
671
672 int
Py_RunMain(void)673 Py_RunMain(void)
674 {
675 int exitcode = 0;
676
677 pymain_run_python(&exitcode);
678
679 if (Py_FinalizeEx() < 0) {
680 /* Value unlikely to be confused with a non-error exit status or
681 other special meaning */
682 exitcode = 120;
683 }
684
685 pymain_free();
686
687 if (_Py_UnhandledKeyboardInterrupt) {
688 exitcode = exit_sigint();
689 }
690
691 return exitcode;
692 }
693
694
695 static int
pymain_main(_PyArgv * args)696 pymain_main(_PyArgv *args)
697 {
698 PyStatus status = pymain_init(args);
699 if (_PyStatus_IS_EXIT(status)) {
700 pymain_free();
701 return status.exitcode;
702 }
703 if (_PyStatus_EXCEPTION(status)) {
704 pymain_exit_error(status);
705 }
706
707 return Py_RunMain();
708 }
709
710
711 int
Py_Main(int argc,wchar_t ** argv)712 Py_Main(int argc, wchar_t **argv)
713 {
714 _PyArgv args = {
715 .argc = argc,
716 .use_bytes_argv = 0,
717 .bytes_argv = NULL,
718 .wchar_argv = argv};
719 return pymain_main(&args);
720 }
721
722
723 int
Py_BytesMain(int argc,char ** argv)724 Py_BytesMain(int argc, char **argv)
725 {
726 _PyArgv args = {
727 .argc = argc,
728 .use_bytes_argv = 1,
729 .bytes_argv = argv,
730 .wchar_argv = NULL};
731 return pymain_main(&args);
732 }
733
734 #ifdef __cplusplus
735 }
736 #endif
737