blob: 6a7f735ed692af33c1970718e06f9319986f5911 [file] [log] [blame]
Guido van Rossum667d7041995-08-04 04:20:48 +00001/* Python interpreter main program */
2
3#include "Python.h"
Victor Stinnerf684d832019-03-01 03:44:13 +01004#include "pycore_coreconfig.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01005#include "pycore_pylifecycle.h"
6#include "pycore_pymem.h"
7#include "pycore_pystate.h"
Guido van Rossum667d7041995-08-04 04:20:48 +00008
Victor Stinner6efcb6d2017-12-18 23:42:55 +01009#ifdef __FreeBSD__
Victor Stinner95e2cbf2019-03-01 16:25:19 +010010# include <fenv.h> /* fedisableexcept() */
Martin v. Löwis945362c2007-08-30 14:57:25 +000011#endif
12
Victor Stinner95e2cbf2019-03-01 16:25:19 +010013/* Includes for exit_sigint() */
14#include <stdio.h> /* perror() */
15#ifdef HAVE_SIGNAL_H
16# include <signal.h> /* SIGINT */
Guido van Rossuma075ce11997-12-05 21:56:45 +000017#endif
Victor Stinner95e2cbf2019-03-01 16:25:19 +010018#if defined(HAVE_GETPID) && defined(HAVE_UNISTD_H)
19# include <unistd.h> /* getpid() */
20#endif
21#ifdef _MSC_VER
22# include <crtdbg.h> /* STATUS_CONTROL_C_EXIT */
23#endif
24/* End of includes for exit_sigint() */
Guido van Rossuma075ce11997-12-05 21:56:45 +000025
Guido van Rossuma22865e2000-09-05 04:41:18 +000026#define COPYRIGHT \
Guido van Rossum36002d72001-07-18 16:59:46 +000027 "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
28 "for more information."
Guido van Rossuma22865e2000-09-05 04:41:18 +000029
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000030#ifdef __cplusplus
31extern "C" {
32#endif
33
Victor Stinner95e2cbf2019-03-01 16:25:19 +010034/* --- pymain_init() ---------------------------------------------- */
35
Victor Stinner6dcb5422019-03-05 02:44:12 +010036static _PyInitError
Victor Stinner5ac27a52019-03-27 13:40:14 +010037pymain_init(const _PyArgv *args)
Victor Stinner95e2cbf2019-03-01 16:25:19 +010038{
39 _PyInitError err;
40
41 err = _PyRuntime_Initialize();
42 if (_Py_INIT_FAILED(err)) {
43 return err;
44 }
45
46 /* 754 requires that FP exceptions run in "no stop" mode by default,
47 * and until C vendors implement C99's ways to control FP exceptions,
48 * Python requires non-stop mode. Alas, some platforms enable FP
49 * exceptions by default. Here we disable them.
50 */
51#ifdef __FreeBSD__
52 fedisableexcept(FE_OVERFLOW);
53#endif
54
Victor Stinnerd929f182019-03-27 18:28:46 +010055 _PyPreConfig preconfig = _PyPreConfig_INIT;
56 /* Set to -1 to enable them depending on the LC_CTYPE locale and the
57 environment variables (PYTHONUTF8 and PYTHONCOERCECLOCALE) */
58 preconfig.coerce_c_locale = -1;
59 preconfig.utf8_mode = -1;
Victor Stinner5ac27a52019-03-27 13:40:14 +010060 if (args->use_bytes_argv) {
Victor Stinnerd929f182019-03-27 18:28:46 +010061 err = _Py_PreInitializeFromArgs(&preconfig,
62 args->argc, args->bytes_argv);
Victor Stinner5ac27a52019-03-27 13:40:14 +010063 }
64 else {
Victor Stinnerd929f182019-03-27 18:28:46 +010065 err = _Py_PreInitializeFromWideArgs(&preconfig,
66 args->argc, args->wchar_argv);
Victor Stinner5ac27a52019-03-27 13:40:14 +010067 }
Victor Stinner6dcb5422019-03-05 02:44:12 +010068 if (_Py_INIT_FAILED(err)) {
Victor Stinnerf72346c2019-03-25 17:54:58 +010069 return err;
Victor Stinner6dcb5422019-03-05 02:44:12 +010070 }
71
Victor Stinnerd929f182019-03-27 18:28:46 +010072 /* pass NULL as the config: config is read from command line arguments,
73 environment variables, configuration files */
Victor Stinner5ac27a52019-03-27 13:40:14 +010074 if (args->use_bytes_argv) {
Victor Stinnerd929f182019-03-27 18:28:46 +010075 return _Py_InitializeFromArgs(NULL, args->argc, args->bytes_argv);
Victor Stinner484f20d2019-03-27 02:04:16 +010076 }
Victor Stinner5ac27a52019-03-27 13:40:14 +010077 else {
Victor Stinnerd929f182019-03-27 18:28:46 +010078 return _Py_InitializeFromWideArgs(NULL, args->argc, args->wchar_argv);
Victor Stinner484f20d2019-03-27 02:04:16 +010079 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +010080}
81
82
83/* --- pymain_run_python() ---------------------------------------- */
84
85/* Non-zero if filename, command (-c) or module (-m) is set
86 on the command line */
87#define RUN_CODE(config) \
88 (config->run_command != NULL || config->run_filename != NULL \
89 || config->run_module != NULL)
90
91/* Return non-zero is stdin is a TTY or if -i command line option is used */
92static int
93stdin_is_interactive(const _PyCoreConfig *config)
94{
95 return (isatty(fileno(stdin)) || config->interactive);
96}
97
98
99static PyObject *
100pymain_get_importer(const wchar_t *filename)
101{
102 PyObject *sys_path0 = NULL, *importer;
103
104 sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename));
105 if (sys_path0 == NULL) {
106 goto error;
107 }
108
109 importer = PyImport_GetImporter(sys_path0);
110 if (importer == NULL) {
111 goto error;
112 }
113
114 if (importer == Py_None) {
115 Py_DECREF(sys_path0);
116 Py_DECREF(importer);
117 return NULL;
118 }
119
120 Py_DECREF(importer);
121 return sys_path0;
122
123error:
124 Py_XDECREF(sys_path0);
125 PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n");
126 PyErr_Print();
127 return NULL;
128}
129
130
131static int
132pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
133{
134 _Py_IDENTIFIER(path);
135 PyObject *sys_path;
136 PyObject *sysdict = interp->sysdict;
137 if (sysdict != NULL) {
138 sys_path = _PyDict_GetItemIdWithError(sysdict, &PyId_path);
139 if (sys_path == NULL && PyErr_Occurred()) {
140 goto error;
141 }
142 }
143 else {
144 sys_path = NULL;
145 }
146 if (sys_path == NULL) {
147 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
148 goto error;
149 }
150
151 if (PyList_Insert(sys_path, 0, path0)) {
152 goto error;
153 }
154 return 0;
155
156error:
157 PyErr_Print();
158 return -1;
159}
160
161
162static void
163pymain_header(const _PyCoreConfig *config)
164{
165 if (config->quiet) {
166 return;
167 }
168
169 if (!config->verbose && (RUN_CODE(config) || !stdin_is_interactive(config))) {
170 return;
171 }
172
173 fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
174 if (config->site_import) {
175 fprintf(stderr, "%s\n", COPYRIGHT);
176 }
177}
178
179
180static void
181pymain_import_readline(const _PyCoreConfig *config)
182{
Victor Stinner20004952019-03-26 02:31:11 +0100183 if (config->isolated) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100184 return;
185 }
186 if (!config->inspect && RUN_CODE(config)) {
187 return;
188 }
189 if (!isatty(fileno(stdin))) {
190 return;
191 }
192
193 PyObject *mod = PyImport_ImportModule("readline");
194 if (mod == NULL) {
195 PyErr_Clear();
196 }
197 else {
198 Py_DECREF(mod);
199 }
200}
201
202
203static int
204pymain_run_command(wchar_t *command, PyCompilerFlags *cf)
205{
206 PyObject *unicode, *bytes;
207 int ret;
208
209 unicode = PyUnicode_FromWideChar(command, -1);
210 if (unicode == NULL) {
211 goto error;
212 }
213
214 bytes = PyUnicode_AsUTF8String(unicode);
215 Py_DECREF(unicode);
216 if (bytes == NULL) {
217 goto error;
218 }
219
220 ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf);
221 Py_DECREF(bytes);
222 return (ret != 0);
223
224error:
225 PySys_WriteStderr("Unable to decode the command from the command line:\n");
226 PyErr_Print();
227 return 1;
228}
229
230
231static int
232pymain_run_module(const wchar_t *modname, int set_argv0)
233{
234 PyObject *module, *runpy, *runmodule, *runargs, *result;
235 runpy = PyImport_ImportModule("runpy");
236 if (runpy == NULL) {
237 fprintf(stderr, "Could not import runpy module\n");
238 PyErr_Print();
239 return -1;
240 }
241 runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
242 if (runmodule == NULL) {
243 fprintf(stderr, "Could not access runpy._run_module_as_main\n");
244 PyErr_Print();
245 Py_DECREF(runpy);
246 return -1;
247 }
248 module = PyUnicode_FromWideChar(modname, wcslen(modname));
249 if (module == NULL) {
250 fprintf(stderr, "Could not convert module name to unicode\n");
251 PyErr_Print();
252 Py_DECREF(runpy);
253 Py_DECREF(runmodule);
254 return -1;
255 }
256 runargs = Py_BuildValue("(Oi)", module, set_argv0);
257 if (runargs == NULL) {
258 fprintf(stderr,
259 "Could not create arguments for runpy._run_module_as_main\n");
260 PyErr_Print();
261 Py_DECREF(runpy);
262 Py_DECREF(runmodule);
263 Py_DECREF(module);
264 return -1;
265 }
266 result = PyObject_Call(runmodule, runargs, NULL);
267 if (result == NULL) {
268 PyErr_Print();
269 }
270 Py_DECREF(runpy);
271 Py_DECREF(runmodule);
272 Py_DECREF(module);
273 Py_DECREF(runargs);
274 if (result == NULL) {
275 return -1;
276 }
277 Py_DECREF(result);
278 return 0;
279}
280
281
282static int
283pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
284{
285 const wchar_t *filename = config->run_filename;
Inada Naoki10654c12019-04-01 18:35:20 +0900286 FILE *fp = _Py_wfopen(filename, L"rb");
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100287 if (fp == NULL) {
288 char *cfilename_buffer;
289 const char *cfilename;
290 int err = errno;
291 cfilename_buffer = _Py_EncodeLocaleRaw(filename, NULL);
292 if (cfilename_buffer != NULL)
293 cfilename = cfilename_buffer;
294 else
295 cfilename = "<unprintable file name>";
296 fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
297 config->program, cfilename, err, strerror(err));
298 PyMem_RawFree(cfilename_buffer);
299 return 2;
300 }
301
302 if (config->skip_source_first_line) {
303 int ch;
304 /* Push back first newline so line numbers remain the same */
305 while ((ch = getc(fp)) != EOF) {
306 if (ch == '\n') {
307 (void)ungetc(ch, fp);
308 break;
309 }
310 }
311 }
312
313 struct _Py_stat_struct sb;
314 if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) {
315 fprintf(stderr,
316 "%ls: '%ls' is a directory, cannot continue\n",
317 config->program, filename);
318 fclose(fp);
319 return 1;
320 }
321
322 /* call pending calls like signal handlers (SIGINT) */
323 if (Py_MakePendingCalls() == -1) {
324 PyErr_Print();
325 fclose(fp);
326 return 1;
327 }
328
329 PyObject *unicode, *bytes = NULL;
330 const char *filename_str;
331
332 unicode = PyUnicode_FromWideChar(filename, wcslen(filename));
333 if (unicode != NULL) {
334 bytes = PyUnicode_EncodeFSDefault(unicode);
335 Py_DECREF(unicode);
336 }
337 if (bytes != NULL) {
338 filename_str = PyBytes_AsString(bytes);
339 }
340 else {
341 PyErr_Clear();
342 filename_str = "<filename encoding error>";
343 }
344
345 /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */
346 int run = PyRun_AnyFileExFlags(fp, filename_str, 1, cf);
347 Py_XDECREF(bytes);
348 return (run != 0);
349}
350
351
352static void
353pymain_run_startup(_PyCoreConfig *config, PyCompilerFlags *cf)
354{
Victor Stinner20004952019-03-26 02:31:11 +0100355 const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100356 if (startup == NULL) {
357 return;
358 }
359
360 FILE *fp = _Py_fopen(startup, "r");
361 if (fp == NULL) {
362 int save_errno = errno;
363 PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
364 errno = save_errno;
365
366 PyErr_SetFromErrnoWithFilename(PyExc_OSError,
367 startup);
368 PyErr_Print();
369 return;
370 }
371
372 (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
373 PyErr_Clear();
374 fclose(fp);
375}
376
377
378static void
379pymain_run_interactive_hook(void)
380{
381 PyObject *sys, *hook, *result;
382 sys = PyImport_ImportModule("sys");
383 if (sys == NULL) {
384 goto error;
385 }
386
387 hook = PyObject_GetAttrString(sys, "__interactivehook__");
388 Py_DECREF(sys);
389 if (hook == NULL) {
390 PyErr_Clear();
391 return;
392 }
393
394 result = _PyObject_CallNoArg(hook);
395 Py_DECREF(hook);
396 if (result == NULL) {
397 goto error;
398 }
399 Py_DECREF(result);
400
401 return;
402
403error:
404 PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
405 PyErr_Print();
406}
407
408
409static int
410pymain_run_stdin(_PyCoreConfig *config, PyCompilerFlags *cf)
411{
412 if (stdin_is_interactive(config)) {
413 Py_InspectFlag = 0; /* do exit on SystemExit */
414 config->inspect = 0;
415 pymain_run_startup(config, cf);
416 pymain_run_interactive_hook();
417 }
418
419 /* call pending calls like signal handlers (SIGINT) */
420 if (Py_MakePendingCalls() == -1) {
421 PyErr_Print();
422 return 1;
423 }
424
425 int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, cf);
426 return (run != 0);
427}
428
429
430static void
431pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
432{
433 /* Check this environment variable at the end, to give programs the
434 opportunity to set it from Python. */
Victor Stinner20004952019-03-26 02:31:11 +0100435 if (!Py_InspectFlag && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100436 Py_InspectFlag = 1;
437 config->inspect = 1;
438 }
439
440 if (!(Py_InspectFlag && stdin_is_interactive(config) && RUN_CODE(config))) {
441 return;
442 }
443
444 Py_InspectFlag = 0;
445 config->inspect = 0;
446 pymain_run_interactive_hook();
447
448 int res = PyRun_AnyFileFlags(stdin, "<stdin>", cf);
449 *exitcode = (res != 0);
450}
451
452
453static _PyInitError
Victor Stinner5ac27a52019-03-27 13:40:14 +0100454pymain_run_python(int *exitcode)
Victor Stinnerb5fd9ad2017-12-14 02:20:52 +0100455{
Victor Stinnerdfe88472019-03-01 12:14:41 +0100456 _PyInitError err;
Victor Stinner5ac27a52019-03-27 13:40:14 +0100457
458 PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
459 /* pymain_run_stdin() modify the config */
Victor Stinnerd3b19192018-07-25 10:21:03 +0200460 _PyCoreConfig *config = &interp->core_config;
461
462 PyObject *main_importer_path = NULL;
Victor Stinner62be7632019-03-01 13:10:14 +0100463 if (config->run_filename != NULL) {
Victor Stinnerd5dda982017-12-13 17:31:16 +0100464 /* If filename is a package (ex: directory or ZIP file) which contains
465 __main__.py, main_importer_path is set to filename and will be
Victor Stinnerd3b19192018-07-25 10:21:03 +0200466 prepended to sys.path.
467
468 Otherwise, main_importer_path is set to NULL. */
Victor Stinner62be7632019-03-01 13:10:14 +0100469 main_importer_path = pymain_get_importer(config->run_filename);
Victor Stinnerd5dda982017-12-13 17:31:16 +0100470 }
471
Victor Stinnerd3b19192018-07-25 10:21:03 +0200472 if (main_importer_path != NULL) {
473 if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) {
Victor Stinnerdfe88472019-03-01 12:14:41 +0100474 err = _Py_INIT_EXIT(1);
Victor Stinnerd3b19192018-07-25 10:21:03 +0200475 goto done;
476 }
Victor Stinnerd5dda982017-12-13 17:31:16 +0100477 }
Victor Stinner20004952019-03-26 02:31:11 +0100478 else if (!config->isolated) {
Victor Stinnerdcf61712019-03-19 16:09:27 +0100479 PyObject *path0 = NULL;
480 if (_PyPathConfig_ComputeSysPath0(&config->argv, &path0)) {
481 if (path0 == NULL) {
482 err = _Py_INIT_NO_MEMORY();
483 goto done;
484 }
Victor Stinner19760862017-12-20 01:41:59 +0100485
Victor Stinnerdcf61712019-03-19 16:09:27 +0100486 if (pymain_sys_path_add_path0(interp, path0) < 0) {
487 Py_DECREF(path0);
488 err = _Py_INIT_EXIT(1);
489 goto done;
490 }
Victor Stinner19760862017-12-20 01:41:59 +0100491 Py_DECREF(path0);
Victor Stinner19760862017-12-20 01:41:59 +0100492 }
Victor Stinner19760862017-12-20 01:41:59 +0100493 }
Victor Stinnera7368ac2017-11-15 18:11:45 -0800494
Guido van Rossum495da292019-03-07 12:38:08 -0800495 PyCompilerFlags cf = {.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION};
Victor Stinnera7368ac2017-11-15 18:11:45 -0800496
Victor Stinner62be7632019-03-01 13:10:14 +0100497 pymain_header(config);
498 pymain_import_readline(config);
Victor Stinnera7368ac2017-11-15 18:11:45 -0800499
Victor Stinner62be7632019-03-01 13:10:14 +0100500 if (config->run_command) {
501 *exitcode = pymain_run_command(config->run_command, &cf);
Victor Stinnera7368ac2017-11-15 18:11:45 -0800502 }
Victor Stinner62be7632019-03-01 13:10:14 +0100503 else if (config->run_module) {
504 *exitcode = (pymain_run_module(config->run_module, 1) != 0);
Victor Stinnera7368ac2017-11-15 18:11:45 -0800505 }
Victor Stinnerd3b19192018-07-25 10:21:03 +0200506 else if (main_importer_path != NULL) {
507 int sts = pymain_run_module(L"__main__", 0);
Victor Stinnerdfe88472019-03-01 12:14:41 +0100508 *exitcode = (sts != 0);
Victor Stinnerd3b19192018-07-25 10:21:03 +0200509 }
Victor Stinner62be7632019-03-01 13:10:14 +0100510 else if (config->run_filename != NULL) {
511 *exitcode = pymain_run_file(config, &cf);
Victor Stinner72ec3192018-08-02 19:34:20 +0200512 }
Victor Stinnera7368ac2017-11-15 18:11:45 -0800513 else {
Victor Stinner62be7632019-03-01 13:10:14 +0100514 *exitcode = pymain_run_stdin(config, &cf);
Victor Stinnera7368ac2017-11-15 18:11:45 -0800515 }
Victor Stinner9cfc0022017-12-20 19:36:46 +0100516
Victor Stinner62be7632019-03-01 13:10:14 +0100517 pymain_repl(config, &cf, exitcode);
Victor Stinnerdfe88472019-03-01 12:14:41 +0100518 err = _Py_INIT_OK();
Victor Stinnerd3b19192018-07-25 10:21:03 +0200519
520done:
521 Py_XDECREF(main_importer_path);
Victor Stinnerdfe88472019-03-01 12:14:41 +0100522 return err;
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800523}
524
Victor Stinnera7368ac2017-11-15 18:11:45 -0800525
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100526/* --- pymain_main() ---------------------------------------------- */
527
528static void
529pymain_free(void)
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800530{
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100531 _PyImport_Fini2();
Victor Stinnerdfe88472019-03-01 12:14:41 +0100532
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100533 /* Free global variables which cannot be freed in Py_Finalize():
534 configuration options set before Py_Initialize() which should
535 remain valid after Py_Finalize(), since
536 Py_Initialize()-Py_Finalize() can be called multiple times. */
537 _PyPathConfig_ClearGlobal();
538 _Py_ClearStandardStreamEncoding();
539 _Py_ClearArgcArgv();
Victor Stinnerf5f336a2019-03-19 14:53:58 +0100540 _PyRuntime_Finalize();
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100541}
Victor Stinner94540602017-12-16 04:54:22 +0100542
Victor Stinner53b7d4e2018-07-25 01:37:05 +0200543
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100544static int
545exit_sigint(void)
546{
547 /* bpo-1054041: We need to exit via the
548 * SIG_DFL handler for SIGINT if KeyboardInterrupt went unhandled.
549 * If we don't, a calling process such as a shell may not know
550 * about the user's ^C. https://www.cons.org/cracauer/sigint.html */
551#if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
552 if (PyOS_setsig(SIGINT, SIG_DFL) == SIG_ERR) {
553 perror("signal"); /* Impossible in normal environments. */
554 } else {
555 kill(getpid(), SIGINT);
Victor Stinner19760862017-12-20 01:41:59 +0100556 }
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100557 /* If setting SIG_DFL failed, or kill failed to terminate us,
558 * there isn't much else we can do aside from an error code. */
559#endif /* HAVE_GETPID && !MS_WINDOWS */
560#ifdef MS_WINDOWS
561 /* cmd.exe detects this, prints ^C, and offers to terminate. */
562 /* https://msdn.microsoft.com/en-us/library/cc704588.aspx */
563 return STATUS_CONTROL_C_EXIT;
564#else
565 return SIGINT + 128;
566#endif /* !MS_WINDOWS */
Victor Stinner1dc6e392018-07-25 02:49:17 +0200567}
568
569
Victor Stinner2f549082019-03-29 15:13:46 +0100570static void _Py_NO_RETURN
571pymain_exit_error(_PyInitError err)
Victor Stinner1dc6e392018-07-25 02:49:17 +0200572{
Victor Stinner2f549082019-03-29 15:13:46 +0100573 pymain_free();
574 _Py_ExitInitError(err);
575}
Victor Stinner1dc6e392018-07-25 02:49:17 +0200576
Victor Stinnerdfe88472019-03-01 12:14:41 +0100577
Victor Stinner2f549082019-03-29 15:13:46 +0100578int
579_Py_RunMain(void)
580{
Victor Stinnerdfe88472019-03-01 12:14:41 +0100581 int exitcode = 0;
Victor Stinner2f549082019-03-29 15:13:46 +0100582
583 _PyInitError err = pymain_run_python(&exitcode);
Victor Stinnerdfe88472019-03-01 12:14:41 +0100584 if (_Py_INIT_FAILED(err)) {
Victor Stinner2f549082019-03-29 15:13:46 +0100585 pymain_exit_error(err);
Victor Stinnerdfe88472019-03-01 12:14:41 +0100586 }
587
588 if (Py_FinalizeEx() < 0) {
589 /* Value unlikely to be confused with a non-error exit status or
590 other special meaning */
591 exitcode = 120;
Victor Stinner19760862017-12-20 01:41:59 +0100592 }
593
Victor Stinner62be7632019-03-01 13:10:14 +0100594 pymain_free();
Victor Stinner94540602017-12-16 04:54:22 +0100595
Gregory P. Smith38f11cc2019-02-16 12:57:40 -0800596 if (_Py_UnhandledKeyboardInterrupt) {
Victor Stinner95e2cbf2019-03-01 16:25:19 +0100597 exitcode = exit_sigint();
Gregory P. Smith38f11cc2019-02-16 12:57:40 -0800598 }
599
Victor Stinnerdfe88472019-03-01 12:14:41 +0100600 return exitcode;
Victor Stinner2f549082019-03-29 15:13:46 +0100601}
Victor Stinnerc1834442019-03-18 22:24:28 +0100602
Victor Stinner2f549082019-03-29 15:13:46 +0100603
604static int
605pymain_main(_PyArgv *args)
606{
607 _PyInitError err = pymain_init(args);
608 if (_Py_INIT_FAILED(err)) {
609 pymain_exit_error(err);
610 }
611
612 return _Py_RunMain();
Victor Stinner94540602017-12-16 04:54:22 +0100613}
614
615
Victor Stinnerf7e5b562017-11-15 15:48:08 -0800616int
617Py_Main(int argc, wchar_t **argv)
618{
Victor Stinner62be7632019-03-01 13:10:14 +0100619 _PyArgv args = {
620 .argc = argc,
621 .use_bytes_argv = 0,
622 .bytes_argv = NULL,
623 .wchar_argv = argv};
624 return pymain_main(&args);
Guido van Rossum667d7041995-08-04 04:20:48 +0000625}
626
Victor Stinner94540602017-12-16 04:54:22 +0100627
628int
629_Py_UnixMain(int argc, char **argv)
630{
Victor Stinner62be7632019-03-01 13:10:14 +0100631 _PyArgv args = {
632 .argc = argc,
633 .use_bytes_argv = 1,
634 .bytes_argv = argv,
635 .wchar_argv = NULL};
636 return pymain_main(&args);
Victor Stinner94540602017-12-16 04:54:22 +0100637}
638
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000639#ifdef __cplusplus
640}
641#endif