• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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