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