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
pymain_init(const _PyArgv * args)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 */
config_run_code(const PyConfig * config)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
stdin_is_interactive(const PyConfig * config)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
pymain_err_print(int * exitcode_p)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
pymain_exit_err_print(void)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
pymain_get_importer(const wchar_t * filename,PyObject ** importer_p,int * exitcode)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
pymain_sys_path_add_path0(PyInterpreterState * interp,PyObject * path0)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
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 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
pymain_run_command(wchar_t * command)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
pymain_run_module(const wchar_t * modname,int set_argv0)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
pymain_run_file_obj(PyObject * program_name,PyObject * filename,int skip_source_first_line)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
pymain_run_file(const PyConfig * config)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
pymain_run_startup(PyConfig * config,int * exitcode)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
pymain_run_interactive_hook(int * exitcode)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
pymain_run_stdin(PyConfig * config)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
pymain_repl(PyConfig * config,int * exitcode)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
pymain_run_python(int * exitcode)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
pymain_free(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
exit_sigint(void)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
pymain_exit_error(PyStatus status)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
Py_RunMain(void)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
pymain_main(_PyArgv * args)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
Py_Main(int argc,wchar_t ** argv)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
Py_BytesMain(int argc,char ** argv)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
740