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