1 /* Python interpreter main program */
2
3 #include "Python.h"
4 #include "osdefs.h"
5 #include "internal/import.h"
6 #include "internal/pygetopt.h"
7 #include "internal/pystate.h"
8
9 #include <locale.h>
10
11 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
12 # include <windows.h>
13 # ifdef HAVE_IO_H
14 # include <io.h>
15 # endif
16 # ifdef HAVE_FCNTL_H
17 # include <fcntl.h>
18 # endif
19 #endif
20
21 #ifdef _MSC_VER
22 # include <crtdbg.h>
23 #endif
24
25 #ifdef __FreeBSD__
26 # include <fenv.h>
27 #endif
28
29 #if defined(MS_WINDOWS)
30 # define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
31 #else
32 # define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
33 #endif
34
35 #define COPYRIGHT \
36 "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
37 "for more information."
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 #define DECODE_LOCALE_ERR(NAME, LEN) \
44 (((LEN) == -2) \
45 ? _Py_INIT_USER_ERR("cannot decode " NAME) \
46 : _Py_INIT_NO_MEMORY())
47
48
49 #define SET_DECODE_ERROR(NAME, LEN) \
50 do { \
51 if ((LEN) == (size_t)-2) { \
52 pymain->err = _Py_INIT_USER_ERR("cannot decode " NAME); \
53 } \
54 else { \
55 pymain->err = _Py_INIT_NO_MEMORY(); \
56 } \
57 } while (0)
58
59 #ifdef MS_WINDOWS
60 #define WCSTOK wcstok_s
61 #else
62 #define WCSTOK wcstok
63 #endif
64
65 /* For Py_GetArgcArgv(); set by main() */
66 static wchar_t **orig_argv = NULL;
67 static int orig_argc = 0;
68
69 /* command line options */
70 #define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
71
72 #define PROGRAM_OPTS BASE_OPTS
73
74 static const _PyOS_LongOption longoptions[] = {
75 {L"check-hash-based-pycs", 1, 0},
76 {NULL, 0, 0},
77 };
78
79 /* Short usage message (with %s for argv0) */
80 static const char usage_line[] =
81 "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
82
83 /* Long usage message, split into parts < 512 bytes */
84 static const char usage_1[] = "\
85 Options and arguments (and corresponding environment variables):\n\
86 -b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
87 and comparing bytes/bytearray with str. (-bb: issue errors)\n\
88 -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\
89 -c cmd : program passed in as string (terminates option list)\n\
90 -d : debug output from parser; also PYTHONDEBUG=x\n\
91 -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
92 -h : print this help message and exit (also --help)\n\
93 ";
94 static const char usage_2[] = "\
95 -i : inspect interactively after running script; forces a prompt even\n\
96 if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
97 -I : isolate Python from the user's environment (implies -E and -s)\n\
98 -m mod : run library module as a script (terminates option list)\n\
99 -O : remove assert and __debug__-dependent statements; add .opt-1 before\n\
100 .pyc extension; also PYTHONOPTIMIZE=x\n\
101 -OO : do -O changes and also discard docstrings; add .opt-2 before\n\
102 .pyc extension\n\
103 -q : don't print version and copyright messages on interactive startup\n\
104 -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
105 -S : don't imply 'import site' on initialization\n\
106 ";
107 static const char usage_3[] = "\
108 -u : force the stdout and stderr streams to be unbuffered;\n\
109 this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\
110 -v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
111 can be supplied multiple times to increase verbosity\n\
112 -V : print the Python version number and exit (also --version)\n\
113 when given twice, print more information about the build\n\
114 -W arg : warning control; arg is action:message:category:module:lineno\n\
115 also PYTHONWARNINGS=arg\n\
116 -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
117 -X opt : set implementation-specific option\n\
118 --check-hash-based-pycs always|default|never:\n\
119 control how Python invalidates hash-based .pyc files\n\
120 ";
121 static const char usage_4[] = "\
122 file : program read from script file\n\
123 - : program read from stdin (default; interactive mode if a tty)\n\
124 arg ...: arguments passed to program in sys.argv[1:]\n\n\
125 Other environment variables:\n\
126 PYTHONSTARTUP: file executed on interactive startup (no default)\n\
127 PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
128 default module search path. The result is sys.path.\n\
129 ";
130 static const char usage_5[] =
131 "PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
132 " The default module search path uses %s.\n"
133 "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
134 "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
135 "PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
136 static const char usage_6[] =
137 "PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
138 " to seed the hashes of str, bytes and datetime objects. It can also be\n"
139 " set to an integer in the range [0,4294967295] to get hash values with a\n"
140 " predictable seed.\n"
141 "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
142 " on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
143 " hooks.\n"
144 "PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
145 " coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n"
146 " locale coercion and locale compatibility warnings on stderr.\n"
147 "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n"
148 " debugger. It can be set to the callable of your debugger of choice.\n"
149 "PYTHONDEVMODE: enable the development mode.\n";
150
151 static void
pymain_usage(int error,const wchar_t * program)152 pymain_usage(int error, const wchar_t* program)
153 {
154 FILE *f = error ? stderr : stdout;
155
156 fprintf(f, usage_line, program);
157 if (error)
158 fprintf(f, "Try `python -h' for more information.\n");
159 else {
160 fputs(usage_1, f);
161 fputs(usage_2, f);
162 fputs(usage_3, f);
163 fprintf(f, usage_4, (wint_t)DELIM);
164 fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
165 fputs(usage_6, f);
166 }
167 }
168
169
170 static const char*
config_get_env_var(const char * name)171 config_get_env_var(const char *name)
172 {
173 const char *var = Py_GETENV(name);
174 if (var && var[0] != '\0') {
175 return var;
176 }
177 else {
178 return NULL;
179 }
180 }
181
182
183 static int
config_get_env_var_dup(wchar_t ** dest,wchar_t * wname,char * name)184 config_get_env_var_dup(wchar_t **dest, wchar_t *wname, char *name)
185 {
186 if (Py_IgnoreEnvironmentFlag) {
187 *dest = NULL;
188 return 0;
189 }
190
191 #ifdef MS_WINDOWS
192 const wchar_t *var = _wgetenv(wname);
193 if (!var || var[0] == '\0') {
194 *dest = NULL;
195 return 0;
196 }
197
198 wchar_t *copy = _PyMem_RawWcsdup(var);
199 if (copy == NULL) {
200 return -1;
201 }
202
203 *dest = copy;
204 #else
205 const char *var = getenv(name);
206 if (!var || var[0] == '\0') {
207 *dest = NULL;
208 return 0;
209 }
210
211 size_t len;
212 wchar_t *wvar = Py_DecodeLocale(var, &len);
213 if (!wvar) {
214 if (len == (size_t)-2) {
215 return -2;
216 }
217 else {
218 return -1;
219 }
220 }
221 *dest = wvar;
222 #endif
223 return 0;
224 }
225
226
227 static void
pymain_run_startup(PyCompilerFlags * cf)228 pymain_run_startup(PyCompilerFlags *cf)
229 {
230 const char *startup = config_get_env_var("PYTHONSTARTUP");
231 if (startup == NULL) {
232 return;
233 }
234
235 FILE *fp = _Py_fopen(startup, "r");
236 if (fp == NULL) {
237 int save_errno = errno;
238 PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
239 errno = save_errno;
240
241 PyErr_SetFromErrnoWithFilename(PyExc_OSError,
242 startup);
243 PyErr_Print();
244 PyErr_Clear();
245 return;
246 }
247
248 (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
249 PyErr_Clear();
250 fclose(fp);
251 }
252
253 static void
pymain_run_interactive_hook(void)254 pymain_run_interactive_hook(void)
255 {
256 PyObject *sys, *hook, *result;
257 sys = PyImport_ImportModule("sys");
258 if (sys == NULL) {
259 goto error;
260 }
261
262 hook = PyObject_GetAttrString(sys, "__interactivehook__");
263 Py_DECREF(sys);
264 if (hook == NULL) {
265 PyErr_Clear();
266 return;
267 }
268
269 result = _PyObject_CallNoArg(hook);
270 Py_DECREF(hook);
271 if (result == NULL) {
272 goto error;
273 }
274 Py_DECREF(result);
275
276 return;
277
278 error:
279 PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
280 PyErr_Print();
281 PyErr_Clear();
282 }
283
284
285 static int
pymain_run_module(const wchar_t * modname,int set_argv0)286 pymain_run_module(const wchar_t *modname, int set_argv0)
287 {
288 PyObject *module, *runpy, *runmodule, *runargs, *result;
289 runpy = PyImport_ImportModule("runpy");
290 if (runpy == NULL) {
291 fprintf(stderr, "Could not import runpy module\n");
292 PyErr_Print();
293 return -1;
294 }
295 runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
296 if (runmodule == NULL) {
297 fprintf(stderr, "Could not access runpy._run_module_as_main\n");
298 PyErr_Print();
299 Py_DECREF(runpy);
300 return -1;
301 }
302 module = PyUnicode_FromWideChar(modname, wcslen(modname));
303 if (module == NULL) {
304 fprintf(stderr, "Could not convert module name to unicode\n");
305 PyErr_Print();
306 Py_DECREF(runpy);
307 Py_DECREF(runmodule);
308 return -1;
309 }
310 runargs = Py_BuildValue("(Oi)", module, set_argv0);
311 if (runargs == NULL) {
312 fprintf(stderr,
313 "Could not create arguments for runpy._run_module_as_main\n");
314 PyErr_Print();
315 Py_DECREF(runpy);
316 Py_DECREF(runmodule);
317 Py_DECREF(module);
318 return -1;
319 }
320 result = PyObject_Call(runmodule, runargs, NULL);
321 if (result == NULL) {
322 PyErr_Print();
323 }
324 Py_DECREF(runpy);
325 Py_DECREF(runmodule);
326 Py_DECREF(module);
327 Py_DECREF(runargs);
328 if (result == NULL) {
329 return -1;
330 }
331 Py_DECREF(result);
332 return 0;
333 }
334
335 static PyObject *
pymain_get_importer(const wchar_t * filename)336 pymain_get_importer(const wchar_t *filename)
337 {
338 PyObject *sys_path0 = NULL, *importer;
339
340 sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename));
341 if (sys_path0 == NULL) {
342 goto error;
343 }
344
345 importer = PyImport_GetImporter(sys_path0);
346 if (importer == NULL) {
347 goto error;
348 }
349
350 if (importer == Py_None) {
351 Py_DECREF(sys_path0);
352 Py_DECREF(importer);
353 return NULL;
354 }
355
356 Py_DECREF(importer);
357 return sys_path0;
358
359 error:
360 Py_XDECREF(sys_path0);
361 PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n");
362 PyErr_Print();
363 PyErr_Clear();
364 return NULL;
365 }
366
367
368 static int
pymain_run_command(wchar_t * command,PyCompilerFlags * cf)369 pymain_run_command(wchar_t *command, PyCompilerFlags *cf)
370 {
371 PyObject *unicode, *bytes;
372 int ret;
373
374 unicode = PyUnicode_FromWideChar(command, -1);
375 if (unicode == NULL) {
376 goto error;
377 }
378
379 bytes = PyUnicode_AsUTF8String(unicode);
380 Py_DECREF(unicode);
381 if (bytes == NULL) {
382 goto error;
383 }
384
385 ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf);
386 Py_DECREF(bytes);
387 return (ret != 0);
388
389 error:
390 PySys_WriteStderr("Unable to decode the command from the command line:\n");
391 PyErr_Print();
392 return 1;
393 }
394
395
396 static int
pymain_run_file(FILE * fp,const wchar_t * filename,PyCompilerFlags * p_cf)397 pymain_run_file(FILE *fp, const wchar_t *filename, PyCompilerFlags *p_cf)
398 {
399 PyObject *unicode, *bytes = NULL;
400 const char *filename_str;
401 int run;
402
403 /* call pending calls like signal handlers (SIGINT) */
404 if (Py_MakePendingCalls() == -1) {
405 PyErr_Print();
406 return 1;
407 }
408
409 if (filename) {
410 unicode = PyUnicode_FromWideChar(filename, wcslen(filename));
411 if (unicode != NULL) {
412 bytes = PyUnicode_EncodeFSDefault(unicode);
413 Py_DECREF(unicode);
414 }
415 if (bytes != NULL) {
416 filename_str = PyBytes_AsString(bytes);
417 }
418 else {
419 PyErr_Clear();
420 filename_str = "<encoding error>";
421 }
422 }
423 else {
424 filename_str = "<stdin>";
425 }
426
427 run = PyRun_AnyFileExFlags(fp, filename_str, filename != NULL, p_cf);
428 Py_XDECREF(bytes);
429 return run != 0;
430 }
431
432
433 /* Main program */
434
435 typedef struct {
436 wchar_t **argv;
437 int nwarnoption; /* Number of -W options */
438 wchar_t **warnoptions; /* -W options */
439 int nenv_warnoption; /* Number of PYTHONWARNINGS options */
440 wchar_t **env_warnoptions; /* PYTHONWARNINGS options */
441 int print_help; /* -h, -? options */
442 int print_version; /* -V option */
443 int bytes_warning; /* Py_BytesWarningFlag, -b */
444 int debug; /* Py_DebugFlag, -b, PYTHONDEBUG */
445 int inspect; /* Py_InspectFlag, -i, PYTHONINSPECT */
446 int interactive; /* Py_InteractiveFlag, -i */
447 int isolated; /* Py_IsolatedFlag, -I */
448 int optimization_level; /* Py_OptimizeFlag, -O, PYTHONOPTIMIZE */
449 int dont_write_bytecode; /* Py_DontWriteBytecodeFlag, -B, PYTHONDONTWRITEBYTECODE */
450 int no_user_site_directory; /* Py_NoUserSiteDirectory, -I, -s, PYTHONNOUSERSITE */
451 int no_site_import; /* Py_NoSiteFlag, -S */
452 int use_unbuffered_io; /* Py_UnbufferedStdioFlag, -u, PYTHONUNBUFFERED */
453 int verbosity; /* Py_VerboseFlag, -v, PYTHONVERBOSE */
454 int quiet_flag; /* Py_QuietFlag, -q */
455 const char *check_hash_pycs_mode; /* --check-hash-based-pycs */
456 #ifdef MS_WINDOWS
457 int legacy_windows_fs_encoding; /* Py_LegacyWindowsFSEncodingFlag,
458 PYTHONLEGACYWINDOWSFSENCODING */
459 int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
460 PYTHONLEGACYWINDOWSSTDIO */
461 #endif
462 } _PyCmdline;
463
464 /* Structure used by Py_Main() to pass data to subfunctions */
465 typedef struct {
466 /* Input arguments */
467 int argc;
468 int use_bytes_argv;
469 char **bytes_argv;
470 wchar_t **wchar_argv;
471
472 /* Exit status or "exit code": result of pymain_main() */
473 int status;
474 /* Error message if a function failed */
475 _PyInitError err;
476
477 /* non-zero is stdin is a TTY or if -i option is used */
478 int stdin_is_interactive;
479 int skip_first_line; /* -x option */
480 wchar_t *filename; /* Trailing arg without -c or -m */
481 wchar_t *command; /* -c argument */
482 wchar_t *module; /* -m argument */
483
484 PyObject *main_importer_path;
485 } _PyMain;
486
487 #define _PyMain_INIT {.err = _Py_INIT_OK()}
488 /* Note: _PyMain_INIT sets other fields to 0/NULL */
489
490
491 /* Non-zero if filename, command (-c) or module (-m) is set
492 on the command line */
493 #define RUN_CODE(pymain) \
494 (pymain->command != NULL || pymain->filename != NULL \
495 || pymain->module != NULL)
496
497
498 static wchar_t*
pymain_wstrdup(_PyMain * pymain,const wchar_t * str)499 pymain_wstrdup(_PyMain *pymain, const wchar_t *str)
500 {
501 wchar_t *str2 = _PyMem_RawWcsdup(str);
502 if (str2 == NULL) {
503 pymain->err = _Py_INIT_NO_MEMORY();
504 return NULL;
505 }
506 return str2;
507 }
508
509
510 static void
clear_wstrlist(int len,wchar_t ** list)511 clear_wstrlist(int len, wchar_t **list)
512 {
513 for (int i=0; i < len; i++) {
514 PyMem_RawFree(list[i]);
515 }
516 PyMem_RawFree(list);
517 }
518
519
520 static int
pymain_init_cmdline_argv(_PyMain * pymain,_PyCoreConfig * config,_PyCmdline * cmdline)521 pymain_init_cmdline_argv(_PyMain *pymain, _PyCoreConfig *config,
522 _PyCmdline *cmdline)
523 {
524 assert(cmdline->argv == NULL);
525
526 if (pymain->use_bytes_argv) {
527 /* +1 for a the NULL terminator */
528 size_t size = sizeof(wchar_t*) * (pymain->argc + 1);
529 wchar_t** argv = (wchar_t **)PyMem_RawMalloc(size);
530 if (argv == NULL) {
531 pymain->err = _Py_INIT_NO_MEMORY();
532 return -1;
533 }
534
535 for (int i = 0; i < pymain->argc; i++) {
536 size_t len;
537 wchar_t *arg = Py_DecodeLocale(pymain->bytes_argv[i], &len);
538 if (arg == NULL) {
539 clear_wstrlist(i, argv);
540 pymain->err = DECODE_LOCALE_ERR("command line arguments",
541 (Py_ssize_t)len);
542 return -1;
543 }
544 argv[i] = arg;
545 }
546 argv[pymain->argc] = NULL;
547
548 cmdline->argv = argv;
549 }
550 else {
551 cmdline->argv = pymain->wchar_argv;
552 }
553
554 wchar_t *program;
555 if (pymain->argc >= 1 && cmdline->argv != NULL) {
556 program = cmdline->argv[0];
557 }
558 else {
559 program = L"";
560 }
561 config->program = pymain_wstrdup(pymain, program);
562 if (config->program == NULL) {
563 return -1;
564 }
565
566 return 0;
567 }
568
569
570 static void
pymain_clear_cmdline(_PyMain * pymain,_PyCmdline * cmdline)571 pymain_clear_cmdline(_PyMain *pymain, _PyCmdline *cmdline)
572 {
573 PyMemAllocatorEx old_alloc;
574 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
575
576 clear_wstrlist(cmdline->nwarnoption, cmdline->warnoptions);
577 cmdline->nwarnoption = 0;
578 cmdline->warnoptions = NULL;
579
580 clear_wstrlist(cmdline->nenv_warnoption, cmdline->env_warnoptions);
581 cmdline->nenv_warnoption = 0;
582 cmdline->env_warnoptions = NULL;
583
584 if (pymain->use_bytes_argv && cmdline->argv != NULL) {
585 clear_wstrlist(pymain->argc, cmdline->argv);
586 }
587 cmdline->argv = NULL;
588
589 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
590 }
591
592
593 static void
pymain_clear_pymain(_PyMain * pymain)594 pymain_clear_pymain(_PyMain *pymain)
595 {
596 #define CLEAR(ATTR) \
597 do { \
598 PyMem_RawFree(ATTR); \
599 ATTR = NULL; \
600 } while (0)
601
602 CLEAR(pymain->filename);
603 CLEAR(pymain->command);
604 CLEAR(pymain->module);
605 #undef CLEAR
606 }
607
608 static void
pymain_clear_config(_PyCoreConfig * config)609 pymain_clear_config(_PyCoreConfig *config)
610 {
611 /* Clear core config with the memory allocator
612 used by pymain_read_conf() */
613 PyMemAllocatorEx old_alloc;
614 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
615
616 _PyCoreConfig_Clear(config);
617
618 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
619 }
620
621
622 static void
pymain_free_python(_PyMain * pymain)623 pymain_free_python(_PyMain *pymain)
624 {
625 Py_CLEAR(pymain->main_importer_path);
626
627 #ifdef __INSURE__
628 /* Insure++ is a memory analysis tool that aids in discovering
629 * memory leaks and other memory problems. On Python exit, the
630 * interned string dictionaries are flagged as being in use at exit
631 * (which it is). Under normal circumstances, this is fine because
632 * the memory will be automatically reclaimed by the system. Under
633 * memory debugging, it's a huge source of useless noise, so we
634 * trade off slower shutdown for less distraction in the memory
635 * reports. -baw
636 */
637 _Py_ReleaseInternedUnicodeStrings();
638 #endif /* __INSURE__ */
639 }
640
641
642 static void
pymain_free_raw(_PyMain * pymain)643 pymain_free_raw(_PyMain *pymain)
644 {
645 _PyImport_Fini2();
646
647 /* Free global variables which cannot be freed in Py_Finalize():
648 configuration options set before Py_Initialize() which should
649 remain valid after Py_Finalize(), since
650 Py_Initialize()-Py_Finalize() can be called multiple times. */
651 _PyPathConfig_Clear(&_Py_path_config);
652
653 /* Force the allocator used by pymain_read_conf() */
654 PyMemAllocatorEx old_alloc;
655 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
656
657 pymain_clear_pymain(pymain);
658
659 clear_wstrlist(orig_argc, orig_argv);
660 orig_argc = 0;
661 orig_argv = NULL;
662
663 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
664 }
665
666
667 static void
pymain_free(_PyMain * pymain)668 pymain_free(_PyMain *pymain)
669 {
670 pymain_free_python(pymain);
671 pymain_free_raw(pymain);
672 }
673
674
675 static int
pymain_run_main_from_importer(_PyMain * pymain)676 pymain_run_main_from_importer(_PyMain *pymain)
677 {
678 /* Assume sys_path0 has already been checked by pymain_get_importer(),
679 * so put it in sys.path[0] and import __main__ */
680 PyObject *sys_path = PySys_GetObject("path");
681 if (sys_path == NULL) {
682 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
683 goto error;
684 }
685
686 if (PyList_Insert(sys_path, 0, pymain->main_importer_path)) {
687 goto error;
688 }
689
690 int sts = pymain_run_module(L"__main__", 0);
691 return (sts != 0);
692
693 error:
694 Py_CLEAR(pymain->main_importer_path);
695 PyErr_Print();
696 return 1;
697 }
698
699
700 static _PyInitError
wstrlist_append(int * len,wchar_t *** list,const wchar_t * str)701 wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
702 {
703 wchar_t *str2 = _PyMem_RawWcsdup(str);
704 if (str2 == NULL) {
705 return _Py_INIT_NO_MEMORY();
706 }
707
708 size_t size = (*len + 1) * sizeof(list[0]);
709 wchar_t **list2 = (wchar_t **)PyMem_RawRealloc(*list, size);
710 if (list2 == NULL) {
711 PyMem_RawFree(str2);
712 return _Py_INIT_NO_MEMORY();
713 }
714 list2[*len] = str2;
715 *list = list2;
716 (*len)++;
717 return _Py_INIT_OK();
718 }
719
720
721 static int
pymain_wstrlist_append(_PyMain * pymain,int * len,wchar_t *** list,const wchar_t * str)722 pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str)
723 {
724 _PyInitError err = wstrlist_append(len, list, str);
725 if (_Py_INIT_FAILED(err)) {
726 pymain->err = err;
727 return -1;
728 }
729 return 0;
730 }
731
732
733 /* Parse the command line arguments
734 Return 0 on success.
735 Return 1 if parsing failed.
736 Set pymain->err and return -1 on other errors. */
737 static int
pymain_parse_cmdline_impl(_PyMain * pymain,_PyCoreConfig * config,_PyCmdline * cmdline)738 pymain_parse_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
739 _PyCmdline *cmdline)
740 {
741 _PyOS_ResetGetOpt();
742 do {
743 int longindex = -1;
744 int c = _PyOS_GetOpt(pymain->argc, cmdline->argv, PROGRAM_OPTS,
745 longoptions, &longindex);
746 if (c == EOF) {
747 break;
748 }
749
750 if (c == 'c') {
751 /* -c is the last option; following arguments
752 that look like options are left for the
753 command to interpret. */
754 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
755 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
756 if (command == NULL) {
757 pymain->err = _Py_INIT_NO_MEMORY();
758 return -1;
759 }
760 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
761 command[len - 2] = '\n';
762 command[len - 1] = 0;
763 pymain->command = command;
764 break;
765 }
766
767 if (c == 'm') {
768 /* -m is the last option; following arguments
769 that look like options are left for the
770 module to interpret. */
771 pymain->module = pymain_wstrdup(pymain, _PyOS_optarg);
772 if (pymain->module == NULL) {
773 return -1;
774 }
775 break;
776 }
777
778 switch (c) {
779 case 0:
780 // Handle long option.
781 assert(longindex == 0); // Only one long option now.
782 if (!wcscmp(_PyOS_optarg, L"always")) {
783 cmdline->check_hash_pycs_mode = "always";
784 } else if (!wcscmp(_PyOS_optarg, L"never")) {
785 cmdline->check_hash_pycs_mode = "never";
786 } else if (!wcscmp(_PyOS_optarg, L"default")) {
787 cmdline->check_hash_pycs_mode = "default";
788 } else {
789 fprintf(stderr, "--check-hash-based-pycs must be one of "
790 "'default', 'always', or 'never'\n");
791 return 1;
792 }
793 break;
794
795 case 'b':
796 cmdline->bytes_warning++;
797 break;
798
799 case 'd':
800 cmdline->debug++;
801 break;
802
803 case 'i':
804 cmdline->inspect++;
805 cmdline->interactive++;
806 break;
807
808 case 'I':
809 config->ignore_environment++;
810 cmdline->isolated++;
811 cmdline->no_user_site_directory++;
812 break;
813
814 /* case 'J': reserved for Jython */
815
816 case 'O':
817 cmdline->optimization_level++;
818 break;
819
820 case 'B':
821 cmdline->dont_write_bytecode++;
822 break;
823
824 case 's':
825 cmdline->no_user_site_directory++;
826 break;
827
828 case 'S':
829 cmdline->no_site_import++;
830 break;
831
832 case 'E':
833 config->ignore_environment++;
834 break;
835
836 case 't':
837 /* ignored for backwards compatibility */
838 break;
839
840 case 'u':
841 cmdline->use_unbuffered_io = 1;
842 break;
843
844 case 'v':
845 cmdline->verbosity++;
846 break;
847
848 case 'x':
849 pymain->skip_first_line = 1;
850 break;
851
852 case 'h':
853 case '?':
854 cmdline->print_help++;
855 break;
856
857 case 'V':
858 cmdline->print_version++;
859 break;
860
861 case 'W':
862 if (pymain_wstrlist_append(pymain,
863 &cmdline->nwarnoption,
864 &cmdline->warnoptions,
865 _PyOS_optarg) < 0) {
866 return -1;
867 }
868 break;
869
870 case 'X':
871 if (pymain_wstrlist_append(pymain,
872 &config->nxoption,
873 &config->xoptions,
874 _PyOS_optarg) < 0) {
875 return -1;
876 }
877 break;
878
879 case 'q':
880 cmdline->quiet_flag++;
881 break;
882
883 case 'R':
884 config->use_hash_seed = 0;
885 break;
886
887 /* This space reserved for other options */
888
889 default:
890 /* unknown argument: parsing failed */
891 return 1;
892 }
893 } while (1);
894
895 if (pymain->command == NULL && pymain->module == NULL
896 && _PyOS_optind < pymain->argc
897 && wcscmp(cmdline->argv[_PyOS_optind], L"-") != 0)
898 {
899 pymain->filename = pymain_wstrdup(pymain, cmdline->argv[_PyOS_optind]);
900 if (pymain->filename == NULL) {
901 return -1;
902 }
903 }
904
905 /* -c and -m options are exclusive */
906 assert(!(pymain->command != NULL && pymain->module != NULL));
907
908 return 0;
909 }
910
911
912 static int
add_xoption(PyObject * opts,const wchar_t * s)913 add_xoption(PyObject *opts, const wchar_t *s)
914 {
915 PyObject *name, *value;
916
917 const wchar_t *name_end = wcschr(s, L'=');
918 if (!name_end) {
919 name = PyUnicode_FromWideChar(s, -1);
920 value = Py_True;
921 Py_INCREF(value);
922 }
923 else {
924 name = PyUnicode_FromWideChar(s, name_end - s);
925 value = PyUnicode_FromWideChar(name_end + 1, -1);
926 }
927 if (name == NULL || value == NULL) {
928 goto error;
929 }
930 if (PyDict_SetItem(opts, name, value) < 0) {
931 goto error;
932 }
933 Py_DECREF(name);
934 Py_DECREF(value);
935 return 0;
936
937 error:
938 Py_XDECREF(name);
939 Py_XDECREF(value);
940 return -1;
941 }
942
943
944 static PyObject*
config_create_xoptions_dict(const _PyCoreConfig * config)945 config_create_xoptions_dict(const _PyCoreConfig *config)
946 {
947 int nxoption = config->nxoption;
948 wchar_t **xoptions = config->xoptions;
949 PyObject *dict = PyDict_New();
950 if (dict == NULL) {
951 return NULL;
952 }
953
954 for (int i=0; i < nxoption; i++) {
955 wchar_t *option = xoptions[i];
956 if (add_xoption(dict, option) < 0) {
957 Py_DECREF(dict);
958 return NULL;
959 }
960 }
961
962 return dict;
963 }
964
965
966 static _PyInitError
config_add_warnings_optlist(_PyCoreConfig * config,int len,wchar_t ** options)967 config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)
968 {
969 for (int i = 0; i < len; i++) {
970 _PyInitError err = wstrlist_append(&config->nwarnoption,
971 &config->warnoptions,
972 options[i]);
973 if (_Py_INIT_FAILED(err)) {
974 return err;
975 }
976 }
977 return _Py_INIT_OK();
978 }
979
980
981 static _PyInitError
config_init_warnoptions(_PyCoreConfig * config,_PyCmdline * cmdline)982 config_init_warnoptions(_PyCoreConfig *config, _PyCmdline *cmdline)
983 {
984 _PyInitError err;
985
986 assert(config->nwarnoption == 0);
987
988 /* The priority order for warnings configuration is (highest precedence
989 * first):
990 *
991 * - the BytesWarning filter, if needed ('-b', '-bb')
992 * - any '-W' command line options; then
993 * - the 'PYTHONWARNINGS' environment variable; then
994 * - the dev mode filter ('-X dev', 'PYTHONDEVMODE'); then
995 * - any implicit filters added by _warnings.c/warnings.py
996 *
997 * All settings except the last are passed to the warnings module via
998 * the `sys.warnoptions` list. Since the warnings module works on the basis
999 * of "the most recently added filter will be checked first", we add
1000 * the lowest precedence entries first so that later entries override them.
1001 */
1002
1003 if (config->dev_mode) {
1004 err = wstrlist_append(&config->nwarnoption,
1005 &config->warnoptions,
1006 L"default");
1007 if (_Py_INIT_FAILED(err)) {
1008 return err;
1009 }
1010 }
1011
1012 err = config_add_warnings_optlist(config,
1013 cmdline->nenv_warnoption,
1014 cmdline->env_warnoptions);
1015 if (_Py_INIT_FAILED(err)) {
1016 return err;
1017 }
1018
1019 err = config_add_warnings_optlist(config,
1020 cmdline->nwarnoption,
1021 cmdline->warnoptions);
1022 if (_Py_INIT_FAILED(err)) {
1023 return err;
1024 }
1025
1026 /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
1027 * don't even try to emit a warning, so we skip setting the filter in that
1028 * case.
1029 */
1030 if (cmdline->bytes_warning) {
1031 wchar_t *filter;
1032 if (cmdline->bytes_warning> 1) {
1033 filter = L"error::BytesWarning";
1034 }
1035 else {
1036 filter = L"default::BytesWarning";
1037 }
1038 err = wstrlist_append(&config->nwarnoption,
1039 &config->warnoptions,
1040 filter);
1041 if (_Py_INIT_FAILED(err)) {
1042 return err;
1043 }
1044 }
1045 return _Py_INIT_OK();
1046 }
1047
1048
1049 /* Get warning options from PYTHONWARNINGS environment variable.
1050 Return 0 on success.
1051 Set pymain->err and return -1 on error. */
1052 static _PyInitError
cmdline_init_env_warnoptions(_PyCmdline * cmdline)1053 cmdline_init_env_warnoptions(_PyCmdline *cmdline)
1054 {
1055 if (Py_IgnoreEnvironmentFlag) {
1056 return _Py_INIT_OK();
1057 }
1058
1059 wchar_t *env;
1060 int res = config_get_env_var_dup(&env, L"PYTHONWARNINGS", "PYTHONWARNINGS");
1061 if (res < 0) {
1062 return DECODE_LOCALE_ERR("PYTHONWARNINGS", res);
1063 }
1064
1065 if (env == NULL) {
1066 return _Py_INIT_OK();
1067 }
1068
1069
1070 wchar_t *warning, *context = NULL;
1071 for (warning = WCSTOK(env, L",", &context);
1072 warning != NULL;
1073 warning = WCSTOK(NULL, L",", &context))
1074 {
1075 _PyInitError err = wstrlist_append(&cmdline->nenv_warnoption,
1076 &cmdline->env_warnoptions,
1077 warning);
1078 if (_Py_INIT_FAILED(err)) {
1079 PyMem_RawFree(env);
1080 return err;
1081 }
1082 }
1083 PyMem_RawFree(env);
1084 return _Py_INIT_OK();
1085 }
1086
1087
1088 static void
pymain_init_stdio(_PyMain * pymain)1089 pymain_init_stdio(_PyMain *pymain)
1090 {
1091 pymain->stdin_is_interactive = (isatty(fileno(stdin))
1092 || Py_InteractiveFlag);
1093
1094 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
1095 /* don't translate newlines (\r\n <=> \n) */
1096 _setmode(fileno(stdin), O_BINARY);
1097 _setmode(fileno(stdout), O_BINARY);
1098 _setmode(fileno(stderr), O_BINARY);
1099 #endif
1100
1101 if (Py_UnbufferedStdioFlag) {
1102 #ifdef HAVE_SETVBUF
1103 setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
1104 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1105 setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
1106 #else /* !HAVE_SETVBUF */
1107 setbuf(stdin, (char *)NULL);
1108 setbuf(stdout, (char *)NULL);
1109 setbuf(stderr, (char *)NULL);
1110 #endif /* !HAVE_SETVBUF */
1111 }
1112 else if (Py_InteractiveFlag) {
1113 #ifdef MS_WINDOWS
1114 /* Doesn't have to have line-buffered -- use unbuffered */
1115 /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
1116 setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
1117 #else /* !MS_WINDOWS */
1118 #ifdef HAVE_SETVBUF
1119 setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
1120 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
1121 #endif /* HAVE_SETVBUF */
1122 #endif /* !MS_WINDOWS */
1123 /* Leave stderr alone - it should be unbuffered anyway. */
1124 }
1125 }
1126
1127
1128 /* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
1129 environment variables on macOS if available. */
1130 static _PyInitError
config_init_program_name(_PyCoreConfig * config)1131 config_init_program_name(_PyCoreConfig *config)
1132 {
1133 assert(config->program_name == NULL);
1134
1135 /* If Py_SetProgramName() was called, use its value */
1136 const wchar_t *program_name = _Py_path_config.program_name;
1137 if (program_name != NULL) {
1138 config->program_name = _PyMem_RawWcsdup(program_name);
1139 if (config->program_name == NULL) {
1140 return _Py_INIT_NO_MEMORY();
1141 }
1142 return _Py_INIT_OK();
1143 }
1144
1145 #ifdef __APPLE__
1146 /* On MacOS X, when the Python interpreter is embedded in an
1147 application bundle, it gets executed by a bootstrapping script
1148 that does os.execve() with an argv[0] that's different from the
1149 actual Python executable. This is needed to keep the Finder happy,
1150 or rather, to work around Apple's overly strict requirements of
1151 the process name. However, we still need a usable sys.executable,
1152 so the actual executable path is passed in an environment variable.
1153 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
1154 script. */
1155 const char *p = config_get_env_var("PYTHONEXECUTABLE");
1156 if (p != NULL) {
1157 size_t len;
1158 wchar_t* program_name = Py_DecodeLocale(p, &len);
1159 if (program_name == NULL) {
1160 return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment "
1161 "variable", (Py_ssize_t)len);
1162 }
1163 config->program_name = program_name;
1164 return _Py_INIT_OK();
1165 }
1166 #ifdef WITH_NEXT_FRAMEWORK
1167 else {
1168 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
1169 if (pyvenv_launcher && *pyvenv_launcher) {
1170 /* Used by Mac/Tools/pythonw.c to forward
1171 * the argv0 of the stub executable
1172 */
1173 size_t len;
1174 wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
1175 if (program_name == NULL) {
1176 return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment "
1177 "variable", (Py_ssize_t)len);
1178 }
1179 config->program_name = program_name;
1180 return _Py_INIT_OK();
1181 }
1182 }
1183 #endif /* WITH_NEXT_FRAMEWORK */
1184 #endif /* __APPLE__ */
1185
1186 /* Use argv[0] by default, if available */
1187 if (config->program != NULL) {
1188 config->program_name = _PyMem_RawWcsdup(config->program);
1189 if (config->program_name == NULL) {
1190 return _Py_INIT_NO_MEMORY();
1191 }
1192 return _Py_INIT_OK();
1193 }
1194
1195 /* Last fall back: hardcoded string */
1196 #ifdef MS_WINDOWS
1197 const wchar_t *default_program_name = L"python";
1198 #else
1199 const wchar_t *default_program_name = L"python3";
1200 #endif
1201 config->program_name = _PyMem_RawWcsdup(default_program_name);
1202 if (config->program_name == NULL) {
1203 return _Py_INIT_NO_MEMORY();
1204 }
1205 return _Py_INIT_OK();
1206 }
1207
1208
1209 static _PyInitError
config_init_executable(_PyCoreConfig * config)1210 config_init_executable(_PyCoreConfig *config)
1211 {
1212 assert(config->executable == NULL);
1213
1214 /* If Py_SetProgramFullPath() was called, use its value */
1215 const wchar_t *program_full_path = _Py_path_config.program_full_path;
1216 if (program_full_path != NULL) {
1217 config->executable = _PyMem_RawWcsdup(program_full_path);
1218 if (config->executable == NULL) {
1219 return _Py_INIT_NO_MEMORY();
1220 }
1221 return _Py_INIT_OK();
1222 }
1223
1224 return _Py_INIT_OK();
1225 }
1226
1227
1228 static void
pymain_header(_PyMain * pymain)1229 pymain_header(_PyMain *pymain)
1230 {
1231 if (Py_QuietFlag) {
1232 return;
1233 }
1234
1235 if (!Py_VerboseFlag && (RUN_CODE(pymain) || !pymain->stdin_is_interactive)) {
1236 return;
1237 }
1238
1239 fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
1240 if (!Py_NoSiteFlag) {
1241 fprintf(stderr, "%s\n", COPYRIGHT);
1242 }
1243 }
1244
1245
1246 static wchar_t**
copy_wstrlist(int len,wchar_t ** list)1247 copy_wstrlist(int len, wchar_t **list)
1248 {
1249 assert((len > 0 && list != NULL) || len == 0);
1250 size_t size = len * sizeof(list[0]);
1251 wchar_t **list_copy = PyMem_RawMalloc(size);
1252 if (list_copy == NULL) {
1253 return NULL;
1254 }
1255 for (int i=0; i < len; i++) {
1256 wchar_t* arg = _PyMem_RawWcsdup(list[i]);
1257 if (arg == NULL) {
1258 clear_wstrlist(i, list_copy);
1259 return NULL;
1260 }
1261 list_copy[i] = arg;
1262 }
1263 return list_copy;
1264 }
1265
1266
1267 static int
pymain_init_core_argv(_PyMain * pymain,_PyCoreConfig * config,_PyCmdline * cmdline)1268 pymain_init_core_argv(_PyMain *pymain, _PyCoreConfig *config,
1269 _PyCmdline *cmdline)
1270 {
1271 /* Copy argv to be able to modify it (to force -c/-m) */
1272 int argc = pymain->argc - _PyOS_optind;
1273 wchar_t **argv;
1274
1275 if (argc <= 0 || cmdline->argv == NULL) {
1276 /* Ensure at least one (empty) argument is seen */
1277 static wchar_t *empty_argv[1] = {L""};
1278 argc = 1;
1279 argv = copy_wstrlist(1, empty_argv);
1280 }
1281 else {
1282 argv = copy_wstrlist(argc, &cmdline->argv[_PyOS_optind]);
1283 }
1284
1285 if (argv == NULL) {
1286 pymain->err = _Py_INIT_NO_MEMORY();
1287 return -1;
1288 }
1289
1290 wchar_t *arg0 = NULL;
1291 if (pymain->command != NULL) {
1292 /* Force sys.argv[0] = '-c' */
1293 arg0 = L"-c";
1294 }
1295 else if (pymain->module != NULL) {
1296 /* Force sys.argv[0] = '-m'*/
1297 arg0 = L"-m";
1298 }
1299 if (arg0 != NULL) {
1300 arg0 = _PyMem_RawWcsdup(arg0);
1301 if (arg0 == NULL) {
1302 clear_wstrlist(argc, argv);
1303 pymain->err = _Py_INIT_NO_MEMORY();
1304 return -1;
1305 }
1306
1307 assert(argc >= 1);
1308 PyMem_RawFree(argv[0]);
1309 argv[0] = arg0;
1310 }
1311
1312 config->argc = argc;
1313 config->argv = argv;
1314 return 0;
1315 }
1316
1317
1318 static PyObject*
_Py_wstrlist_as_pylist(int len,wchar_t ** list)1319 _Py_wstrlist_as_pylist(int len, wchar_t **list)
1320 {
1321 assert(list != NULL || len < 1);
1322
1323 PyObject *pylist = PyList_New(len);
1324 if (pylist == NULL) {
1325 return NULL;
1326 }
1327
1328 for (int i = 0; i < len; i++) {
1329 PyObject *v = PyUnicode_FromWideChar(list[i], -1);
1330 if (v == NULL) {
1331 Py_DECREF(pylist);
1332 return NULL;
1333 }
1334 PyList_SET_ITEM(pylist, i, v);
1335 }
1336 return pylist;
1337 }
1338
1339
1340 static int
pymain_compute_path0(_PyMain * pymain,_PyCoreConfig * config,PyObject ** path0)1341 pymain_compute_path0(_PyMain *pymain, _PyCoreConfig *config, PyObject **path0)
1342 {
1343 if (pymain->main_importer_path != NULL) {
1344 /* Let pymain_run_main_from_importer() adjust sys.path[0] later */
1345 *path0 = NULL;
1346 return 0;
1347 }
1348
1349 if (Py_IsolatedFlag) {
1350 *path0 = NULL;
1351 return 0;
1352 }
1353
1354 *path0 = _PyPathConfig_ComputeArgv0(config->argc, config->argv);
1355 if (*path0 == NULL) {
1356 pymain->err = _Py_INIT_NO_MEMORY();
1357 return -1;
1358 }
1359 return 0;
1360 }
1361
1362
1363 static int
pymain_update_sys_path(_PyMain * pymain,PyObject * path0)1364 pymain_update_sys_path(_PyMain *pymain, PyObject *path0)
1365 {
1366 /* Prepend argv[0] to sys.path.
1367 If argv[0] is a symlink, use the real path. */
1368 PyObject *sys_path = PySys_GetObject("path");
1369 if (sys_path == NULL) {
1370 pymain->err = _Py_INIT_ERR("can't get sys.path");
1371 return -1;
1372 }
1373
1374 /* Prepend path0 to sys.path */
1375 if (PyList_Insert(sys_path, 0, path0) < 0) {
1376 pymain->err = _Py_INIT_ERR("sys.path.insert(0, path0) failed");
1377 return -1;
1378 }
1379 return 0;
1380 }
1381
1382
1383 PyObject *
_Py_GetGlobalVariablesAsDict(void)1384 _Py_GetGlobalVariablesAsDict(void)
1385 {
1386 PyObject *dict, *obj;
1387
1388 dict = PyDict_New();
1389 if (dict == NULL) {
1390 return NULL;
1391 }
1392
1393 #define SET_ITEM(KEY, EXPR) \
1394 do { \
1395 obj = (EXPR); \
1396 if (obj == NULL) { \
1397 return NULL; \
1398 } \
1399 int res = PyDict_SetItemString(dict, (KEY), obj); \
1400 Py_DECREF(obj); \
1401 if (res < 0) { \
1402 goto fail; \
1403 } \
1404 } while (0)
1405 #define SET_ITEM_INT(VAR) \
1406 SET_ITEM(#VAR, PyLong_FromLong(VAR))
1407 #define FROM_STRING(STR) \
1408 ((STR != NULL) ? \
1409 PyUnicode_FromString(STR) \
1410 : (Py_INCREF(Py_None), Py_None))
1411 #define SET_ITEM_STR(VAR) \
1412 SET_ITEM(#VAR, FROM_STRING(VAR))
1413
1414 SET_ITEM_STR(Py_FileSystemDefaultEncoding);
1415 SET_ITEM_INT(Py_HasFileSystemDefaultEncoding);
1416 SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors);
1417
1418 SET_ITEM_INT(Py_UTF8Mode);
1419 SET_ITEM_INT(Py_DebugFlag);
1420 SET_ITEM_INT(Py_VerboseFlag);
1421 SET_ITEM_INT(Py_QuietFlag);
1422 SET_ITEM_INT(Py_InteractiveFlag);
1423 SET_ITEM_INT(Py_InspectFlag);
1424
1425 SET_ITEM_INT(Py_OptimizeFlag);
1426 SET_ITEM_INT(Py_NoSiteFlag);
1427 SET_ITEM_INT(Py_BytesWarningFlag);
1428 SET_ITEM_INT(Py_FrozenFlag);
1429 SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
1430 SET_ITEM_INT(Py_DontWriteBytecodeFlag);
1431 SET_ITEM_INT(Py_NoUserSiteDirectory);
1432 SET_ITEM_INT(Py_UnbufferedStdioFlag);
1433 SET_ITEM_INT(Py_HashRandomizationFlag);
1434 SET_ITEM_INT(Py_IsolatedFlag);
1435
1436 #ifdef MS_WINDOWS
1437 SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
1438 SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
1439 #endif
1440
1441 return dict;
1442
1443 fail:
1444 Py_DECREF(dict);
1445 return NULL;
1446
1447 #undef FROM_STRING
1448 #undef SET_ITEM
1449 #undef SET_ITEM_INT
1450 #undef SET_ITEM_STR
1451 }
1452
1453
1454 void
_PyCoreConfig_GetGlobalConfig(_PyCoreConfig * config)1455 _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
1456 {
1457 #define COPY_FLAG(ATTR, VALUE) \
1458 if (config->ATTR == -1) { \
1459 config->ATTR = VALUE; \
1460 }
1461
1462 COPY_FLAG(ignore_environment, Py_IgnoreEnvironmentFlag);
1463 COPY_FLAG(utf8_mode, Py_UTF8Mode);
1464
1465 #undef COPY_FLAG
1466 }
1467
1468
1469 /* Get Py_xxx global configuration variables */
1470 static void
cmdline_get_global_config(_PyCmdline * cmdline)1471 cmdline_get_global_config(_PyCmdline *cmdline)
1472 {
1473 cmdline->bytes_warning = Py_BytesWarningFlag;
1474 cmdline->debug = Py_DebugFlag;
1475 cmdline->inspect = Py_InspectFlag;
1476 cmdline->interactive = Py_InteractiveFlag;
1477 cmdline->isolated = Py_IsolatedFlag;
1478 cmdline->optimization_level = Py_OptimizeFlag;
1479 cmdline->dont_write_bytecode = Py_DontWriteBytecodeFlag;
1480 cmdline->no_user_site_directory = Py_NoUserSiteDirectory;
1481 cmdline->no_site_import = Py_NoSiteFlag;
1482 cmdline->use_unbuffered_io = Py_UnbufferedStdioFlag;
1483 cmdline->verbosity = Py_VerboseFlag;
1484 cmdline->quiet_flag = Py_QuietFlag;
1485 #ifdef MS_WINDOWS
1486 cmdline->legacy_windows_fs_encoding = Py_LegacyWindowsFSEncodingFlag;
1487 cmdline->legacy_windows_stdio = Py_LegacyWindowsStdioFlag;
1488 #endif
1489 cmdline->check_hash_pycs_mode = _Py_CheckHashBasedPycsMode ;
1490 }
1491
1492
1493 void
_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig * config)1494 _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
1495 {
1496 Py_IgnoreEnvironmentFlag = config->ignore_environment;
1497 Py_UTF8Mode = config->utf8_mode;
1498
1499 /* Random or non-zero hash seed */
1500 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
1501 config->hash_seed != 0);
1502 }
1503
1504
1505 /* Set Py_xxx global configuration variables */
1506 static void
cmdline_set_global_config(_PyCmdline * cmdline)1507 cmdline_set_global_config(_PyCmdline *cmdline)
1508 {
1509 Py_BytesWarningFlag = cmdline->bytes_warning;
1510 Py_DebugFlag = cmdline->debug;
1511 Py_InspectFlag = cmdline->inspect;
1512 Py_InteractiveFlag = cmdline->interactive;
1513 Py_IsolatedFlag = cmdline->isolated;
1514 Py_OptimizeFlag = cmdline->optimization_level;
1515 Py_DontWriteBytecodeFlag = cmdline->dont_write_bytecode;
1516 Py_NoUserSiteDirectory = cmdline->no_user_site_directory;
1517 Py_NoSiteFlag = cmdline->no_site_import;
1518 Py_UnbufferedStdioFlag = cmdline->use_unbuffered_io;
1519 Py_VerboseFlag = cmdline->verbosity;
1520 Py_QuietFlag = cmdline->quiet_flag;
1521 _Py_CheckHashBasedPycsMode = cmdline->check_hash_pycs_mode;
1522 #ifdef MS_WINDOWS
1523 Py_LegacyWindowsFSEncodingFlag = cmdline->legacy_windows_fs_encoding;
1524 Py_LegacyWindowsStdioFlag = cmdline->legacy_windows_stdio;
1525 #endif
1526 }
1527
1528
1529 static void
pymain_import_readline(_PyMain * pymain)1530 pymain_import_readline(_PyMain *pymain)
1531 {
1532 if (Py_IsolatedFlag) {
1533 return;
1534 }
1535 if (!Py_InspectFlag && RUN_CODE(pymain)) {
1536 return;
1537 }
1538 if (!isatty(fileno(stdin))) {
1539 return;
1540 }
1541
1542 PyObject *mod = PyImport_ImportModule("readline");
1543 if (mod == NULL) {
1544 PyErr_Clear();
1545 }
1546 else {
1547 Py_DECREF(mod);
1548 }
1549 }
1550
1551
1552 static FILE*
pymain_open_filename(_PyMain * pymain)1553 pymain_open_filename(_PyMain *pymain)
1554 {
1555 const _PyCoreConfig *config = &_PyGILState_GetInterpreterStateUnsafe()->core_config;
1556 FILE* fp;
1557
1558 fp = _Py_wfopen(pymain->filename, L"r");
1559 if (fp == NULL) {
1560 char *cfilename_buffer;
1561 const char *cfilename;
1562 int err = errno;
1563 cfilename_buffer = _Py_EncodeLocaleRaw(pymain->filename, NULL);
1564 if (cfilename_buffer != NULL)
1565 cfilename = cfilename_buffer;
1566 else
1567 cfilename = "<unprintable file name>";
1568 fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
1569 config->program, cfilename, err, strerror(err));
1570 PyMem_RawFree(cfilename_buffer);
1571 pymain->status = 2;
1572 return NULL;
1573 }
1574
1575 if (pymain->skip_first_line) {
1576 int ch;
1577 /* Push back first newline so line numbers
1578 remain the same */
1579 while ((ch = getc(fp)) != EOF) {
1580 if (ch == '\n') {
1581 (void)ungetc(ch, fp);
1582 break;
1583 }
1584 }
1585 }
1586
1587 struct _Py_stat_struct sb;
1588 if (_Py_fstat_noraise(fileno(fp), &sb) == 0 &&
1589 S_ISDIR(sb.st_mode)) {
1590 fprintf(stderr,
1591 "%ls: '%ls' is a directory, cannot continue\n",
1592 config->program, pymain->filename);
1593 fclose(fp);
1594 pymain->status = 1;
1595 return NULL;
1596 }
1597
1598 return fp;
1599 }
1600
1601
1602 static void
pymain_run_filename(_PyMain * pymain,PyCompilerFlags * cf)1603 pymain_run_filename(_PyMain *pymain, PyCompilerFlags *cf)
1604 {
1605 if (pymain->filename == NULL && pymain->stdin_is_interactive) {
1606 Py_InspectFlag = 0; /* do exit on SystemExit */
1607 pymain_run_startup(cf);
1608 pymain_run_interactive_hook();
1609 }
1610
1611 if (pymain->main_importer_path != NULL) {
1612 pymain->status = pymain_run_main_from_importer(pymain);
1613 return;
1614 }
1615
1616 FILE *fp;
1617 if (pymain->filename != NULL) {
1618 fp = pymain_open_filename(pymain);
1619 if (fp == NULL) {
1620 return;
1621 }
1622 }
1623 else {
1624 fp = stdin;
1625 }
1626
1627 pymain->status = pymain_run_file(fp, pymain->filename, cf);
1628 }
1629
1630
1631 static void
pymain_repl(_PyMain * pymain,PyCompilerFlags * cf)1632 pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
1633 {
1634 /* Check this environment variable at the end, to give programs the
1635 opportunity to set it from Python. */
1636 if (!Py_InspectFlag && config_get_env_var("PYTHONINSPECT")) {
1637 Py_InspectFlag = 1;
1638 }
1639
1640 if (!(Py_InspectFlag && pymain->stdin_is_interactive && RUN_CODE(pymain))) {
1641 return;
1642 }
1643
1644 Py_InspectFlag = 0;
1645 pymain_run_interactive_hook();
1646
1647 int res = PyRun_AnyFileFlags(stdin, "<stdin>", cf);
1648 pymain->status = (res != 0);
1649 }
1650
1651
1652 /* Parse the command line.
1653 Handle --version and --help options directly.
1654
1655 Return 1 if Python must exit.
1656 Return 0 on success.
1657 Set pymain->err and return -1 on failure. */
1658 static int
pymain_parse_cmdline(_PyMain * pymain,_PyCoreConfig * config,_PyCmdline * cmdline)1659 pymain_parse_cmdline(_PyMain *pymain, _PyCoreConfig *config,
1660 _PyCmdline *cmdline)
1661 {
1662 int res = pymain_parse_cmdline_impl(pymain, config, cmdline);
1663 if (res < 0) {
1664 return -1;
1665 }
1666 if (res) {
1667 pymain_usage(1, config->program);
1668 pymain->status = 2;
1669 return 1;
1670 }
1671
1672 if (pymain->command != NULL || pymain->module != NULL) {
1673 /* Backup _PyOS_optind */
1674 _PyOS_optind--;
1675 }
1676
1677 return 0;
1678 }
1679
1680
1681 static const wchar_t*
config_get_xoption(_PyCoreConfig * config,wchar_t * name)1682 config_get_xoption(_PyCoreConfig *config, wchar_t *name)
1683 {
1684 int nxoption = config->nxoption;
1685 wchar_t **xoptions = config->xoptions;
1686 for (int i=0; i < nxoption; i++) {
1687 wchar_t *option = xoptions[i];
1688 size_t len;
1689 wchar_t *sep = wcschr(option, L'=');
1690 if (sep != NULL) {
1691 len = (sep - option);
1692 }
1693 else {
1694 len = wcslen(option);
1695 }
1696 if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
1697 return option;
1698 }
1699 }
1700 return NULL;
1701 }
1702
1703
1704 static int
pymain_str_to_int(const char * str,int * result)1705 pymain_str_to_int(const char *str, int *result)
1706 {
1707 errno = 0;
1708 const char *endptr = str;
1709 long value = strtol(str, (char **)&endptr, 10);
1710 if (*endptr != '\0' || errno == ERANGE) {
1711 return -1;
1712 }
1713 if (value < INT_MIN || value > INT_MAX) {
1714 return -1;
1715 }
1716
1717 *result = (int)value;
1718 return 0;
1719 }
1720
1721
1722 static int
pymain_wstr_to_int(const wchar_t * wstr,int * result)1723 pymain_wstr_to_int(const wchar_t *wstr, int *result)
1724 {
1725 errno = 0;
1726 const wchar_t *endptr = wstr;
1727 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
1728 if (*endptr != '\0' || errno == ERANGE) {
1729 return -1;
1730 }
1731 if (value < INT_MIN || value > INT_MAX) {
1732 return -1;
1733 }
1734
1735 *result = (int)value;
1736 return 0;
1737 }
1738
1739
1740 static _PyInitError
config_init_tracemalloc(_PyCoreConfig * config)1741 config_init_tracemalloc(_PyCoreConfig *config)
1742 {
1743 int nframe;
1744 int valid;
1745
1746 const char *env = config_get_env_var("PYTHONTRACEMALLOC");
1747 if (env) {
1748 if (!pymain_str_to_int(env, &nframe)) {
1749 valid = (nframe >= 1);
1750 }
1751 else {
1752 valid = 0;
1753 }
1754 if (!valid) {
1755 return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
1756 "of frames");
1757 }
1758 config->tracemalloc = nframe;
1759 }
1760
1761 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
1762 if (xoption) {
1763 const wchar_t *sep = wcschr(xoption, L'=');
1764 if (sep) {
1765 if (!pymain_wstr_to_int(sep + 1, &nframe)) {
1766 valid = (nframe >= 1);
1767 }
1768 else {
1769 valid = 0;
1770 }
1771 if (!valid) {
1772 return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
1773 "invalid number of frames");
1774 }
1775 }
1776 else {
1777 /* -X tracemalloc behaves as -X tracemalloc=1 */
1778 nframe = 1;
1779 }
1780 config->tracemalloc = nframe;
1781 }
1782 return _Py_INIT_OK();
1783 }
1784
1785
1786 static void
get_env_flag(int * flag,const char * name)1787 get_env_flag(int *flag, const char *name)
1788 {
1789 const char *var = config_get_env_var(name);
1790 if (!var) {
1791 return;
1792 }
1793 int value;
1794 if (pymain_str_to_int(var, &value) < 0 || value < 0) {
1795 /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
1796 value = 1;
1797 }
1798 if (*flag < value) {
1799 *flag = value;
1800 }
1801 }
1802
1803
1804 static void
cmdline_get_env_flags(_PyCmdline * cmdline)1805 cmdline_get_env_flags(_PyCmdline *cmdline)
1806 {
1807 get_env_flag(&cmdline->debug, "PYTHONDEBUG");
1808 get_env_flag(&cmdline->verbosity, "PYTHONVERBOSE");
1809 get_env_flag(&cmdline->optimization_level, "PYTHONOPTIMIZE");
1810 get_env_flag(&cmdline->inspect, "PYTHONINSPECT");
1811 get_env_flag(&cmdline->dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
1812 get_env_flag(&cmdline->no_user_site_directory, "PYTHONNOUSERSITE");
1813 get_env_flag(&cmdline->use_unbuffered_io, "PYTHONUNBUFFERED");
1814 #ifdef MS_WINDOWS
1815 get_env_flag(&cmdline->legacy_windows_fs_encoding,
1816 "PYTHONLEGACYWINDOWSFSENCODING");
1817 get_env_flag(&cmdline->legacy_windows_stdio,
1818 "PYTHONLEGACYWINDOWSSTDIO");
1819 #endif
1820 }
1821
1822
1823 /* Set global variable variables from environment variables */
1824 void
_Py_Initialize_ReadEnvVarsNoAlloc(void)1825 _Py_Initialize_ReadEnvVarsNoAlloc(void)
1826 {
1827 _PyCmdline cmdline;
1828 memset(&cmdline, 0, sizeof(cmdline));
1829
1830 cmdline_get_global_config(&cmdline);
1831 if (cmdline.isolated) {
1832 Py_IgnoreEnvironmentFlag = 1;
1833 cmdline.no_user_site_directory = 1;
1834 }
1835 if (!Py_IgnoreEnvironmentFlag) {
1836 cmdline_get_env_flags(&cmdline);
1837 }
1838 cmdline_set_global_config(&cmdline);
1839
1840 /* no need to call pymain_clear_cmdline(), no memory has been allocated */
1841 }
1842
1843
1844 static _PyInitError
config_init_home(_PyCoreConfig * config)1845 config_init_home(_PyCoreConfig *config)
1846 {
1847 wchar_t *home;
1848
1849 /* If Py_SetPythonHome() was called, use its value */
1850 home = _Py_path_config.home;
1851 if (home) {
1852 config->home = _PyMem_RawWcsdup(home);
1853 if (config->home == NULL) {
1854 return _Py_INIT_NO_MEMORY();
1855 }
1856 return _Py_INIT_OK();
1857 }
1858
1859 int res = config_get_env_var_dup(&home, L"PYTHONHOME", "PYTHONHOME");
1860 if (res < 0) {
1861 return DECODE_LOCALE_ERR("PYTHONHOME", res);
1862 }
1863 config->home = home;
1864 return _Py_INIT_OK();
1865 }
1866
1867
1868 static _PyInitError
config_init_hash_seed(_PyCoreConfig * config)1869 config_init_hash_seed(_PyCoreConfig *config)
1870 {
1871 const char *seed_text = config_get_env_var("PYTHONHASHSEED");
1872 int use_hash_seed;
1873 unsigned long hash_seed;
1874 if (_Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) {
1875 return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" "
1876 "or an integer in range [0; 4294967295]");
1877 }
1878 config->use_hash_seed = use_hash_seed;
1879 config->hash_seed = hash_seed;
1880 return _Py_INIT_OK();
1881 }
1882
1883
1884 static _PyInitError
config_init_utf8_mode(_PyCoreConfig * config)1885 config_init_utf8_mode(_PyCoreConfig *config)
1886 {
1887 const wchar_t *xopt = config_get_xoption(config, L"utf8");
1888 if (xopt) {
1889 wchar_t *sep = wcschr(xopt, L'=');
1890 if (sep) {
1891 xopt = sep + 1;
1892 if (wcscmp(xopt, L"1") == 0) {
1893 config->utf8_mode = 1;
1894 }
1895 else if (wcscmp(xopt, L"0") == 0) {
1896 config->utf8_mode = 0;
1897 }
1898 else {
1899 return _Py_INIT_USER_ERR("invalid -X utf8 option value");
1900 }
1901 }
1902 else {
1903 config->utf8_mode = 1;
1904 }
1905 return _Py_INIT_OK();
1906 }
1907
1908 const char *opt = config_get_env_var("PYTHONUTF8");
1909 if (opt) {
1910 if (strcmp(opt, "1") == 0) {
1911 config->utf8_mode = 1;
1912 }
1913 else if (strcmp(opt, "0") == 0) {
1914 config->utf8_mode = 0;
1915 }
1916 else {
1917 return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
1918 "variable value");
1919 }
1920 return _Py_INIT_OK();
1921 }
1922
1923 return _Py_INIT_OK();
1924 }
1925
1926
1927 static _PyInitError
config_read_env_vars(_PyCoreConfig * config)1928 config_read_env_vars(_PyCoreConfig *config)
1929 {
1930 assert(!config->ignore_environment);
1931
1932 if (config->allocator == NULL) {
1933 config->allocator = config_get_env_var("PYTHONMALLOC");
1934 }
1935
1936 if (config_get_env_var("PYTHONDUMPREFS")) {
1937 config->dump_refs = 1;
1938 }
1939 if (config_get_env_var("PYTHONMALLOCSTATS")) {
1940 config->malloc_stats = 1;
1941 }
1942
1943 const char *env = config_get_env_var("PYTHONCOERCECLOCALE");
1944 if (env) {
1945 if (strcmp(env, "0") == 0) {
1946 if (config->coerce_c_locale < 0) {
1947 config->coerce_c_locale = 0;
1948 }
1949 }
1950 else if (strcmp(env, "warn") == 0) {
1951 config->coerce_c_locale_warn = 1;
1952 }
1953 else {
1954 if (config->coerce_c_locale < 0) {
1955 config->coerce_c_locale = 1;
1956 }
1957 }
1958 }
1959
1960 wchar_t *path;
1961 int res = config_get_env_var_dup(&path, L"PYTHONPATH", "PYTHONPATH");
1962 if (res < 0) {
1963 return DECODE_LOCALE_ERR("PYTHONPATH", res);
1964 }
1965 config->module_search_path_env = path;
1966
1967 if (config->use_hash_seed < 0) {
1968 _PyInitError err = config_init_hash_seed(config);
1969 if (_Py_INIT_FAILED(err)) {
1970 return err;
1971 }
1972 }
1973
1974 return _Py_INIT_OK();
1975 }
1976
1977
1978 static _PyInitError
config_read_complex_options(_PyCoreConfig * config)1979 config_read_complex_options(_PyCoreConfig *config)
1980 {
1981 /* More complex options configured by env var and -X option */
1982 if (config->faulthandler < 0) {
1983 if (config_get_env_var("PYTHONFAULTHANDLER")
1984 || config_get_xoption(config, L"faulthandler")) {
1985 config->faulthandler = 1;
1986 }
1987 }
1988 if (config_get_env_var("PYTHONPROFILEIMPORTTIME")
1989 || config_get_xoption(config, L"importtime")) {
1990 config->import_time = 1;
1991 }
1992 if (config_get_xoption(config, L"dev" ) ||
1993 config_get_env_var("PYTHONDEVMODE"))
1994 {
1995 config->dev_mode = 1;
1996 }
1997
1998 if (config->tracemalloc < 0) {
1999 _PyInitError err = config_init_tracemalloc(config);
2000 if (_Py_INIT_FAILED(err)) {
2001 return err;
2002 }
2003 }
2004 return _Py_INIT_OK();
2005 }
2006
2007
2008 /* Parse command line options and environment variables.
2009 This code must not use Python runtime apart PyMem_Raw memory allocator.
2010
2011 Return 0 on success.
2012 Return 1 if Python is done and must exit.
2013 Set pymain->err and return -1 on error. */
2014 static int
pymain_read_conf_impl(_PyMain * pymain,_PyCoreConfig * config,_PyCmdline * cmdline)2015 pymain_read_conf_impl(_PyMain *pymain, _PyCoreConfig *config,
2016 _PyCmdline *cmdline)
2017 {
2018 _PyInitError err;
2019
2020 int res = pymain_parse_cmdline(pymain, config, cmdline);
2021 if (res != 0) {
2022 return res;
2023 }
2024
2025 /* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */
2026 Py_IgnoreEnvironmentFlag = config->ignore_environment || cmdline->isolated;
2027
2028 /* Get environment variables */
2029 if (!Py_IgnoreEnvironmentFlag) {
2030 cmdline_get_env_flags(cmdline);
2031 }
2032
2033 err = cmdline_init_env_warnoptions(cmdline);
2034 if (_Py_INIT_FAILED(err)) {
2035 pymain->err = err;
2036 return -1;
2037 }
2038
2039 #ifdef MS_WINDOWS
2040 if (cmdline->legacy_windows_fs_encoding) {
2041 config->utf8_mode = 0;
2042 }
2043 #endif
2044
2045 if (pymain_init_core_argv(pymain, config, cmdline) < 0) {
2046 return -1;
2047 }
2048
2049 /* On Windows, _PyPathConfig_Init() modifies Py_IsolatedFlag and
2050 Py_NoSiteFlag variables if a "._pth" file is found. */
2051 int init_isolated = Py_IsolatedFlag;
2052 int init_no_site = Py_NoSiteFlag;
2053 Py_IsolatedFlag = cmdline->isolated;
2054 Py_NoSiteFlag = cmdline->no_site_import;
2055
2056 err = _PyCoreConfig_Read(config);
2057
2058 cmdline->isolated = Py_IsolatedFlag;
2059 cmdline->no_site_import = Py_NoSiteFlag;
2060 Py_IsolatedFlag = init_isolated;
2061 Py_NoSiteFlag = init_no_site;
2062
2063 if (_Py_INIT_FAILED(err)) {
2064 pymain->err = err;
2065 return -1;
2066 }
2067 return 0;
2068 }
2069
2070
2071 /* Read the configuration, but initialize also the LC_CTYPE locale:
2072 enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538) */
2073 static int
pymain_read_conf(_PyMain * pymain,_PyCoreConfig * config,_PyCmdline * cmdline)2074 pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline)
2075 {
2076 int init_utf8_mode = Py_UTF8Mode;
2077 _PyCoreConfig save_config = _PyCoreConfig_INIT;
2078 int res = -1;
2079
2080 char *oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
2081 if (oldloc == NULL) {
2082 pymain->err = _Py_INIT_NO_MEMORY();
2083 goto done;
2084 }
2085
2086 /* Reconfigure the locale to the default for this process */
2087 _Py_SetLocaleFromEnv(LC_ALL);
2088
2089 int locale_coerced = 0;
2090 int loops = 0;
2091 int init_ignore_env = config->ignore_environment;
2092
2093 if (_PyCoreConfig_Copy(&save_config, config) < 0) {
2094 pymain->err = _Py_INIT_NO_MEMORY();
2095 goto done;
2096 }
2097
2098 while (1) {
2099 int init_utf8_mode = config->utf8_mode;
2100 int encoding_changed = 0;
2101
2102 /* Watchdog to prevent an infinite loop */
2103 loops++;
2104 if (loops == 3) {
2105 pymain->err = _Py_INIT_ERR("Encoding changed twice while "
2106 "reading the configuration");
2107 goto done;
2108 }
2109
2110 /* bpo-34207: Py_DecodeLocale(), Py_EncodeLocale() and similar
2111 functions depend on Py_UTF8Mode. */
2112 Py_UTF8Mode = config->utf8_mode;
2113
2114 if (pymain_init_cmdline_argv(pymain, config, cmdline) < 0) {
2115 goto done;
2116 }
2117
2118 int conf_res = pymain_read_conf_impl(pymain, config, cmdline);
2119 if (conf_res != 0) {
2120 res = conf_res;
2121 goto done;
2122 }
2123
2124 /* The legacy C locale assumes ASCII as the default text encoding, which
2125 * causes problems not only for the CPython runtime, but also other
2126 * components like GNU readline.
2127 *
2128 * Accordingly, when the CLI detects it, it attempts to coerce it to a
2129 * more capable UTF-8 based alternative.
2130 *
2131 * See the documentation of the PYTHONCOERCECLOCALE setting for more
2132 * details.
2133 */
2134 if (config->coerce_c_locale && !locale_coerced) {
2135 locale_coerced = 1;
2136 _Py_CoerceLegacyLocale(config);
2137 encoding_changed = 1;
2138 }
2139
2140 if (init_utf8_mode == -1) {
2141 if (config->utf8_mode == 1) {
2142 /* UTF-8 Mode enabled */
2143 encoding_changed = 1;
2144 }
2145 }
2146 else {
2147 if (config->utf8_mode != init_utf8_mode) {
2148 encoding_changed = 1;
2149 }
2150 }
2151
2152 if (!encoding_changed) {
2153 break;
2154 }
2155
2156 /* Reset the configuration, except UTF-8 Mode. Set Py_UTF8Mode for
2157 Py_DecodeLocale(). Reset Py_IgnoreEnvironmentFlag, modified by
2158 pymain_read_conf_impl(). Reset Py_IsolatedFlag and Py_NoSiteFlag
2159 modified by _PyCoreConfig_Read(). */
2160 int new_utf8_mode = config->utf8_mode;
2161 int new_coerce_c_locale = config->coerce_c_locale;
2162 Py_IgnoreEnvironmentFlag = init_ignore_env;
2163 if (_PyCoreConfig_Copy(config, &save_config) < 0) {
2164 pymain->err = _Py_INIT_NO_MEMORY();
2165 goto done;
2166 }
2167 pymain_clear_cmdline(pymain, cmdline);
2168 pymain_clear_pymain(pymain);
2169 memset(cmdline, 0, sizeof(*cmdline));
2170
2171 cmdline_get_global_config(cmdline);
2172 _PyCoreConfig_GetGlobalConfig(config);
2173 config->utf8_mode = new_utf8_mode;
2174 config->coerce_c_locale = new_coerce_c_locale;
2175
2176 /* The encoding changed: read again the configuration
2177 with the new encoding */
2178 }
2179 res = 0;
2180
2181 done:
2182 _PyCoreConfig_Clear(&save_config);
2183 if (oldloc != NULL) {
2184 setlocale(LC_ALL, oldloc);
2185 PyMem_RawFree(oldloc);
2186 }
2187 Py_UTF8Mode = init_utf8_mode ;
2188 return res;
2189 }
2190
2191
2192 static void
config_init_locale(_PyCoreConfig * config)2193 config_init_locale(_PyCoreConfig *config)
2194 {
2195 /* Test also if coerce_c_locale equals 1: PYTHONCOERCECLOCALE=1 doesn't
2196 imply that the C locale is always coerced. It is only coerced if
2197 if the LC_CTYPE locale is "C". */
2198 if (config->coerce_c_locale != 0) {
2199 /* The C locale enables the C locale coercion (PEP 538) */
2200 if (_Py_LegacyLocaleDetected()) {
2201 config->coerce_c_locale = 1;
2202 }
2203 else {
2204 config->coerce_c_locale = 0;
2205 }
2206 }
2207
2208 #ifndef MS_WINDOWS
2209 if (config->utf8_mode < 0) {
2210 /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
2211 const char *ctype_loc = setlocale(LC_CTYPE, NULL);
2212 if (ctype_loc != NULL
2213 && (strcmp(ctype_loc, "C") == 0
2214 || strcmp(ctype_loc, "POSIX") == 0))
2215 {
2216 config->utf8_mode = 1;
2217 }
2218 }
2219 #endif
2220 }
2221
2222
2223 static _PyInitError
config_init_module_search_paths(_PyCoreConfig * config)2224 config_init_module_search_paths(_PyCoreConfig *config)
2225 {
2226 assert(config->module_search_paths == NULL);
2227 assert(config->nmodule_search_path < 0);
2228
2229 config->nmodule_search_path = 0;
2230
2231 const wchar_t *sys_path = Py_GetPath();
2232 const wchar_t delim = DELIM;
2233 const wchar_t *p = sys_path;
2234 while (1) {
2235 p = wcschr(sys_path, delim);
2236 if (p == NULL) {
2237 p = sys_path + wcslen(sys_path); /* End of string */
2238 }
2239
2240 size_t path_len = (p - sys_path);
2241 wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t));
2242 if (path == NULL) {
2243 return _Py_INIT_NO_MEMORY();
2244 }
2245 memcpy(path, sys_path, path_len * sizeof(wchar_t));
2246 path[path_len] = L'\0';
2247
2248 _PyInitError err = wstrlist_append(&config->nmodule_search_path,
2249 &config->module_search_paths,
2250 path);
2251 PyMem_RawFree(path);
2252 if (_Py_INIT_FAILED(err)) {
2253 return err;
2254 }
2255
2256 if (*p == '\0') {
2257 break;
2258 }
2259 sys_path = p + 1;
2260 }
2261 return _Py_INIT_OK();
2262 }
2263
2264
2265 static _PyInitError
config_init_path_config(_PyCoreConfig * config)2266 config_init_path_config(_PyCoreConfig *config)
2267 {
2268 _PyInitError err = _PyPathConfig_Init(config);
2269 if (_Py_INIT_FAILED(err)) {
2270 return err;
2271 }
2272
2273 if (config->nmodule_search_path < 0) {
2274 err = config_init_module_search_paths(config);
2275 if (_Py_INIT_FAILED(err)) {
2276 return err;
2277 }
2278 }
2279
2280 if (config->executable == NULL) {
2281 config->executable = _PyMem_RawWcsdup(Py_GetProgramFullPath());
2282 if (config->executable == NULL) {
2283 return _Py_INIT_NO_MEMORY();
2284 }
2285 }
2286
2287 if (config->prefix == NULL) {
2288 config->prefix = _PyMem_RawWcsdup(Py_GetPrefix());
2289 if (config->prefix == NULL) {
2290 return _Py_INIT_NO_MEMORY();
2291 }
2292 }
2293
2294 if (config->exec_prefix == NULL) {
2295 config->exec_prefix = _PyMem_RawWcsdup(Py_GetExecPrefix());
2296 if (config->exec_prefix == NULL) {
2297 return _Py_INIT_NO_MEMORY();
2298 }
2299 }
2300
2301 if (config->base_prefix == NULL) {
2302 config->base_prefix = _PyMem_RawWcsdup(config->prefix);
2303 if (config->base_prefix == NULL) {
2304 return _Py_INIT_NO_MEMORY();
2305 }
2306 }
2307
2308 if (config->base_exec_prefix == NULL) {
2309 config->base_exec_prefix = _PyMem_RawWcsdup(config->exec_prefix);
2310 if (config->base_exec_prefix == NULL) {
2311 return _Py_INIT_NO_MEMORY();
2312 }
2313 }
2314
2315 return _Py_INIT_OK();
2316 }
2317
2318 /* Read configuration settings from standard locations
2319 *
2320 * This function doesn't make any changes to the interpreter state - it
2321 * merely populates any missing configuration settings. This allows an
2322 * embedding application to completely override a config option by
2323 * setting it before calling this function, or else modify the default
2324 * setting before passing the fully populated config to Py_EndInitialization.
2325 *
2326 * More advanced selective initialization tricks are possible by calling
2327 * this function multiple times with various preconfigured settings.
2328 */
2329
2330 _PyInitError
_PyCoreConfig_Read(_PyCoreConfig * config)2331 _PyCoreConfig_Read(_PyCoreConfig *config)
2332 {
2333 _PyInitError err;
2334
2335 _PyCoreConfig_GetGlobalConfig(config);
2336
2337 assert(config->ignore_environment >= 0);
2338 if (!config->ignore_environment) {
2339 err = config_read_env_vars(config);
2340 if (_Py_INIT_FAILED(err)) {
2341 return err;
2342 }
2343 }
2344
2345 /* -X options */
2346 if (config_get_xoption(config, L"showrefcount")) {
2347 config->show_ref_count = 1;
2348 }
2349 if (config_get_xoption(config, L"showalloccount")) {
2350 config->show_alloc_count = 1;
2351 }
2352
2353 err = config_read_complex_options(config);
2354 if (_Py_INIT_FAILED(err)) {
2355 return err;
2356 }
2357
2358 if (config->utf8_mode < 0) {
2359 err = config_init_utf8_mode(config);
2360 if (_Py_INIT_FAILED(err)) {
2361 return err;
2362 }
2363 }
2364
2365 if (config->home == NULL) {
2366 err = config_init_home(config);
2367 if (_Py_INIT_FAILED(err)) {
2368 return err;
2369 }
2370 }
2371
2372 if (config->program_name == NULL) {
2373 err = config_init_program_name(config);
2374 if (_Py_INIT_FAILED(err)) {
2375 return err;
2376 }
2377 }
2378
2379 if (config->executable == NULL) {
2380 err = config_init_executable(config);
2381 if (_Py_INIT_FAILED(err)) {
2382 return err;
2383 }
2384 }
2385
2386 if (config->coerce_c_locale != 0 || config->utf8_mode < 0) {
2387 config_init_locale(config);
2388 }
2389
2390 if (!config->_disable_importlib) {
2391 err = config_init_path_config(config);
2392 if (_Py_INIT_FAILED(err)) {
2393 return err;
2394 }
2395 }
2396
2397 /* default values */
2398 if (config->dev_mode) {
2399 if (config->faulthandler < 0) {
2400 config->faulthandler = 1;
2401 }
2402 if (config->allocator == NULL) {
2403 config->allocator = "debug";
2404 }
2405 }
2406 if (config->install_signal_handlers < 0) {
2407 config->install_signal_handlers = 1;
2408 }
2409 if (config->use_hash_seed < 0) {
2410 config->use_hash_seed = 0;
2411 config->hash_seed = 0;
2412 }
2413 if (config->faulthandler < 0) {
2414 config->faulthandler = 0;
2415 }
2416 if (config->tracemalloc < 0) {
2417 config->tracemalloc = 0;
2418 }
2419 if (config->coerce_c_locale < 0) {
2420 config->coerce_c_locale = 0;
2421 }
2422 if (config->utf8_mode < 0) {
2423 config->utf8_mode = 0;
2424 }
2425 if (config->argc < 0) {
2426 config->argc = 0;
2427 }
2428
2429 return _Py_INIT_OK();
2430 }
2431
2432
2433 void
_PyCoreConfig_Clear(_PyCoreConfig * config)2434 _PyCoreConfig_Clear(_PyCoreConfig *config)
2435 {
2436 #define CLEAR(ATTR) \
2437 do { \
2438 PyMem_RawFree(ATTR); \
2439 ATTR = NULL; \
2440 } while (0)
2441 #define CLEAR_WSTRLIST(LEN, LIST) \
2442 do { \
2443 clear_wstrlist(LEN, LIST); \
2444 LEN = 0; \
2445 LIST = NULL; \
2446 } while (0)
2447
2448 CLEAR(config->module_search_path_env);
2449 CLEAR(config->home);
2450 CLEAR(config->program_name);
2451 CLEAR(config->program);
2452
2453 CLEAR_WSTRLIST(config->argc, config->argv);
2454 config->argc = -1;
2455
2456 CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions);
2457 CLEAR_WSTRLIST(config->nxoption, config->xoptions);
2458 CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths);
2459 config->nmodule_search_path = -1;
2460
2461 CLEAR(config->executable);
2462 CLEAR(config->prefix);
2463 CLEAR(config->base_prefix);
2464 CLEAR(config->exec_prefix);
2465 CLEAR(config->base_exec_prefix);
2466 #undef CLEAR
2467 #undef CLEAR_WSTRLIST
2468 }
2469
2470
2471 int
_PyCoreConfig_Copy(_PyCoreConfig * config,const _PyCoreConfig * config2)2472 _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
2473 {
2474 _PyCoreConfig_Clear(config);
2475
2476 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
2477 #define COPY_STR_ATTR(ATTR) \
2478 do { \
2479 if (config2->ATTR != NULL) { \
2480 config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
2481 if (config->ATTR == NULL) { \
2482 return -1; \
2483 } \
2484 } \
2485 } while (0)
2486 #define COPY_WSTRLIST(LEN, LIST) \
2487 do { \
2488 if (config2->LIST != NULL) { \
2489 config->LIST = copy_wstrlist(config2->LEN, config2->LIST); \
2490 if (config->LIST == NULL) { \
2491 return -1; \
2492 } \
2493 } \
2494 config->LEN = config2->LEN; \
2495 } while (0)
2496
2497 COPY_ATTR(install_signal_handlers);
2498 COPY_ATTR(ignore_environment);
2499 COPY_ATTR(use_hash_seed);
2500 COPY_ATTR(hash_seed);
2501 COPY_ATTR(_disable_importlib);
2502 COPY_ATTR(allocator);
2503 COPY_ATTR(dev_mode);
2504 COPY_ATTR(faulthandler);
2505 COPY_ATTR(tracemalloc);
2506 COPY_ATTR(import_time);
2507 COPY_ATTR(show_ref_count);
2508 COPY_ATTR(show_alloc_count);
2509 COPY_ATTR(dump_refs);
2510 COPY_ATTR(malloc_stats);
2511
2512 COPY_ATTR(coerce_c_locale);
2513 COPY_ATTR(coerce_c_locale_warn);
2514 COPY_ATTR(utf8_mode);
2515
2516 COPY_STR_ATTR(module_search_path_env);
2517 COPY_STR_ATTR(home);
2518 COPY_STR_ATTR(program_name);
2519 COPY_STR_ATTR(program);
2520
2521 COPY_WSTRLIST(argc, argv);
2522 COPY_WSTRLIST(nwarnoption, warnoptions);
2523 COPY_WSTRLIST(nxoption, xoptions);
2524 COPY_WSTRLIST(nmodule_search_path, module_search_paths);
2525
2526 COPY_STR_ATTR(executable);
2527 COPY_STR_ATTR(prefix);
2528 COPY_STR_ATTR(base_prefix);
2529 COPY_STR_ATTR(exec_prefix);
2530 COPY_STR_ATTR(base_exec_prefix);
2531
2532 #undef COPY_ATTR
2533 #undef COPY_STR_ATTR
2534 #undef COPY_WSTRLIST
2535 return 0;
2536 }
2537
2538
2539 PyObject *
_PyCoreConfig_AsDict(const _PyCoreConfig * config)2540 _PyCoreConfig_AsDict(const _PyCoreConfig *config)
2541 {
2542 PyObject *dict, *obj;
2543
2544 dict = PyDict_New();
2545 if (dict == NULL) {
2546 return NULL;
2547 }
2548
2549 #define SET_ITEM(KEY, EXPR) \
2550 do { \
2551 obj = (EXPR); \
2552 if (obj == NULL) { \
2553 return NULL; \
2554 } \
2555 int res = PyDict_SetItemString(dict, (KEY), obj); \
2556 Py_DECREF(obj); \
2557 if (res < 0) { \
2558 goto fail; \
2559 } \
2560 } while (0)
2561 #define FROM_STRING(STR) \
2562 ((STR != NULL) ? \
2563 PyUnicode_FromString(STR) \
2564 : (Py_INCREF(Py_None), Py_None))
2565 #define SET_ITEM_INT(ATTR) \
2566 SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR))
2567 #define SET_ITEM_UINT(ATTR) \
2568 SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR))
2569 #define SET_ITEM_STR(ATTR) \
2570 SET_ITEM(#ATTR, FROM_STRING(config->ATTR))
2571 #define FROM_WSTRING(STR) \
2572 ((STR != NULL) ? \
2573 PyUnicode_FromWideChar(STR, -1) \
2574 : (Py_INCREF(Py_None), Py_None))
2575 #define SET_ITEM_WSTR(ATTR) \
2576 SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
2577 #define SET_ITEM_WSTRLIST(NOPTION, OPTIONS) \
2578 SET_ITEM(#OPTIONS, _Py_wstrlist_as_pylist(config->NOPTION, config->OPTIONS))
2579
2580 SET_ITEM_INT(install_signal_handlers);
2581 SET_ITEM_INT(ignore_environment);
2582 SET_ITEM_INT(use_hash_seed);
2583 SET_ITEM_UINT(hash_seed);
2584 SET_ITEM_STR(allocator);
2585 SET_ITEM_INT(dev_mode);
2586 SET_ITEM_INT(faulthandler);
2587 SET_ITEM_INT(tracemalloc);
2588 SET_ITEM_INT(import_time);
2589 SET_ITEM_INT(show_ref_count);
2590 SET_ITEM_INT(show_alloc_count);
2591 SET_ITEM_INT(dump_refs);
2592 SET_ITEM_INT(malloc_stats);
2593 SET_ITEM_INT(coerce_c_locale);
2594 SET_ITEM_INT(coerce_c_locale_warn);
2595 SET_ITEM_INT(utf8_mode);
2596 SET_ITEM_WSTR(program_name);
2597 SET_ITEM_WSTRLIST(argc, argv);
2598 SET_ITEM_WSTR(program);
2599 SET_ITEM_WSTRLIST(nxoption, xoptions);
2600 SET_ITEM_WSTRLIST(nwarnoption, warnoptions);
2601 SET_ITEM_WSTR(module_search_path_env);
2602 SET_ITEM_WSTR(home);
2603 SET_ITEM_WSTRLIST(nmodule_search_path, module_search_paths);
2604 SET_ITEM_WSTR(executable);
2605 SET_ITEM_WSTR(prefix);
2606 SET_ITEM_WSTR(base_prefix);
2607 SET_ITEM_WSTR(exec_prefix);
2608 SET_ITEM_WSTR(base_exec_prefix);
2609 SET_ITEM_INT(_disable_importlib);
2610
2611 return dict;
2612
2613 fail:
2614 Py_DECREF(dict);
2615 return NULL;
2616
2617 #undef FROM_STRING
2618 #undef FROM_WSTRING
2619 #undef SET_ITEM
2620 #undef SET_ITEM_INT
2621 #undef SET_ITEM_UINT
2622 #undef SET_ITEM_STR
2623 #undef SET_ITEM_WSTR
2624 #undef SET_ITEM_WSTRLIST
2625 }
2626
2627
2628 void
_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig * config)2629 _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
2630 {
2631 Py_CLEAR(config->argv);
2632 Py_CLEAR(config->executable);
2633 Py_CLEAR(config->prefix);
2634 Py_CLEAR(config->base_prefix);
2635 Py_CLEAR(config->exec_prefix);
2636 Py_CLEAR(config->base_exec_prefix);
2637 Py_CLEAR(config->warnoptions);
2638 Py_CLEAR(config->xoptions);
2639 Py_CLEAR(config->module_search_path);
2640 }
2641
2642
2643 static PyObject*
config_copy_attr(PyObject * obj)2644 config_copy_attr(PyObject *obj)
2645 {
2646 if (PyUnicode_Check(obj)) {
2647 Py_INCREF(obj);
2648 return obj;
2649 }
2650 else if (PyList_Check(obj)) {
2651 return PyList_GetSlice(obj, 0, Py_SIZE(obj));
2652 }
2653 else if (PyDict_Check(obj)) {
2654 /* The dict type is used for xoptions. Make the assumption that keys
2655 and values are immutables */
2656 return PyDict_Copy(obj);
2657 }
2658 else {
2659 PyErr_Format(PyExc_TypeError,
2660 "cannot copy config attribute of type %.200s",
2661 Py_TYPE(obj)->tp_name);
2662 return NULL;
2663 }
2664 }
2665
2666
2667 int
_PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig * config,const _PyMainInterpreterConfig * config2)2668 _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,
2669 const _PyMainInterpreterConfig *config2)
2670 {
2671 _PyMainInterpreterConfig_Clear(config);
2672
2673 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
2674 #define COPY_OBJ_ATTR(ATTR) \
2675 do { \
2676 if (config2->ATTR != NULL) { \
2677 config->ATTR = config_copy_attr(config2->ATTR); \
2678 if (config->ATTR == NULL) { \
2679 return -1; \
2680 } \
2681 } \
2682 } while (0)
2683
2684 COPY_ATTR(install_signal_handlers);
2685 COPY_OBJ_ATTR(argv);
2686 COPY_OBJ_ATTR(executable);
2687 COPY_OBJ_ATTR(prefix);
2688 COPY_OBJ_ATTR(base_prefix);
2689 COPY_OBJ_ATTR(exec_prefix);
2690 COPY_OBJ_ATTR(base_exec_prefix);
2691 COPY_OBJ_ATTR(warnoptions);
2692 COPY_OBJ_ATTR(xoptions);
2693 COPY_OBJ_ATTR(module_search_path);
2694 #undef COPY_ATTR
2695 #undef COPY_OBJ_ATTR
2696 return 0;
2697 }
2698
2699
2700 PyObject*
_PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig * config)2701 _PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config)
2702 {
2703 PyObject *dict, *obj;
2704 int res;
2705
2706 dict = PyDict_New();
2707 if (dict == NULL) {
2708 return NULL;
2709 }
2710
2711 #define SET_ITEM_INT(ATTR) \
2712 do { \
2713 obj = PyLong_FromLong(config->ATTR); \
2714 if (obj == NULL) { \
2715 goto fail; \
2716 } \
2717 res = PyDict_SetItemString(dict, #ATTR, obj); \
2718 Py_DECREF(obj); \
2719 if (res < 0) { \
2720 goto fail; \
2721 } \
2722 } while (0)
2723
2724 #define SET_ITEM_OBJ(ATTR) \
2725 do { \
2726 obj = config->ATTR; \
2727 if (obj == NULL) { \
2728 obj = Py_None; \
2729 } \
2730 res = PyDict_SetItemString(dict, #ATTR, obj); \
2731 if (res < 0) { \
2732 goto fail; \
2733 } \
2734 } while (0)
2735
2736 SET_ITEM_INT(install_signal_handlers);
2737 SET_ITEM_OBJ(argv);
2738 SET_ITEM_OBJ(executable);
2739 SET_ITEM_OBJ(prefix);
2740 SET_ITEM_OBJ(base_prefix);
2741 SET_ITEM_OBJ(exec_prefix);
2742 SET_ITEM_OBJ(base_exec_prefix);
2743 SET_ITEM_OBJ(warnoptions);
2744 SET_ITEM_OBJ(xoptions);
2745 SET_ITEM_OBJ(module_search_path);
2746
2747 return dict;
2748
2749 fail:
2750 Py_DECREF(dict);
2751 return NULL;
2752
2753 #undef SET_ITEM_OBJ
2754 }
2755
2756
2757 _PyInitError
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig * main_config,const _PyCoreConfig * config)2758 _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
2759 const _PyCoreConfig *config)
2760 {
2761 if (main_config->install_signal_handlers < 0) {
2762 main_config->install_signal_handlers = config->install_signal_handlers;
2763 }
2764
2765 if (main_config->xoptions == NULL) {
2766 main_config->xoptions = config_create_xoptions_dict(config);
2767 if (main_config->xoptions == NULL) {
2768 return _Py_INIT_NO_MEMORY();
2769 }
2770 }
2771
2772 #define COPY_WSTR(ATTR) \
2773 do { \
2774 if (main_config->ATTR == NULL) { \
2775 main_config->ATTR = PyUnicode_FromWideChar(config->ATTR, -1); \
2776 if (main_config->ATTR == NULL) { \
2777 return _Py_INIT_NO_MEMORY(); \
2778 } \
2779 } \
2780 } while (0)
2781 #define COPY_WSTRLIST(ATTR, LEN, LIST) \
2782 do { \
2783 if (ATTR == NULL) { \
2784 ATTR = _Py_wstrlist_as_pylist(LEN, LIST); \
2785 if (ATTR == NULL) { \
2786 return _Py_INIT_NO_MEMORY(); \
2787 } \
2788 } \
2789 } while (0)
2790
2791 COPY_WSTRLIST(main_config->warnoptions,
2792 config->nwarnoption, config->warnoptions);
2793 if (config->argc >= 0) {
2794 COPY_WSTRLIST(main_config->argv,
2795 config->argc, config->argv);
2796 }
2797
2798 if (!config->_disable_importlib) {
2799 COPY_WSTR(executable);
2800 COPY_WSTR(prefix);
2801 COPY_WSTR(base_prefix);
2802 COPY_WSTR(exec_prefix);
2803 COPY_WSTR(base_exec_prefix);
2804
2805 COPY_WSTRLIST(main_config->module_search_path,
2806 config->nmodule_search_path, config->module_search_paths);
2807 }
2808
2809 return _Py_INIT_OK();
2810 #undef COPY_WSTR
2811 #undef COPY_WSTRLIST
2812 }
2813
2814
2815 static int
pymain_init_python_main(_PyMain * pymain,PyInterpreterState * interp)2816 pymain_init_python_main(_PyMain *pymain, PyInterpreterState *interp)
2817 {
2818 _PyInitError err;
2819
2820 _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
2821 err = _PyMainInterpreterConfig_Read(&main_config, &interp->core_config);
2822 if (!_Py_INIT_FAILED(err)) {
2823 err = _Py_InitializeMainInterpreter(interp, &main_config);
2824 }
2825 _PyMainInterpreterConfig_Clear(&main_config);
2826
2827 if (_Py_INIT_FAILED(err)) {
2828 pymain->err = err;
2829 return -1;
2830 }
2831 return 0;
2832 }
2833
2834
2835 static int
pymain_init_sys_path(_PyMain * pymain,_PyCoreConfig * config)2836 pymain_init_sys_path(_PyMain *pymain, _PyCoreConfig *config)
2837 {
2838 if (pymain->filename != NULL) {
2839 /* If filename is a package (ex: directory or ZIP file) which contains
2840 __main__.py, main_importer_path is set to filename and will be
2841 prepended to sys.path by pymain_run_main_from_importer(). Otherwise,
2842 main_importer_path is set to NULL. */
2843 pymain->main_importer_path = pymain_get_importer(pymain->filename);
2844 }
2845
2846 PyObject *path0;
2847 if (pymain_compute_path0(pymain, config, &path0) < 0) {
2848 return -1;
2849 }
2850
2851 if (path0 != NULL) {
2852 if (pymain_update_sys_path(pymain, path0) < 0) {
2853 Py_DECREF(path0);
2854 return -1;
2855 }
2856 Py_DECREF(path0);
2857 }
2858 return 0;
2859 }
2860
2861
2862 static void
pymain_run_python(_PyMain * pymain)2863 pymain_run_python(_PyMain *pymain)
2864 {
2865 PyCompilerFlags cf = {.cf_flags = 0};
2866
2867 pymain_header(pymain);
2868 pymain_import_readline(pymain);
2869
2870 if (pymain->command) {
2871 pymain->status = pymain_run_command(pymain->command, &cf);
2872 }
2873 else if (pymain->module) {
2874 pymain->status = (pymain_run_module(pymain->module, 1) != 0);
2875 }
2876 else {
2877 pymain_run_filename(pymain, &cf);
2878 }
2879
2880 pymain_repl(pymain, &cf);
2881 }
2882
2883
2884 static int
pymain_cmdline_impl(_PyMain * pymain,_PyCoreConfig * config,_PyCmdline * cmdline)2885 pymain_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config,
2886 _PyCmdline *cmdline)
2887 {
2888 pymain->err = _PyRuntime_Initialize();
2889 if (_Py_INIT_FAILED(pymain->err)) {
2890 return -1;
2891 }
2892
2893 int res = pymain_read_conf(pymain, config, cmdline);
2894 if (res < 0) {
2895 return -1;
2896 }
2897 if (res > 0) {
2898 /* --help or --version command: we are done */
2899 return 1;
2900 }
2901
2902 if (cmdline->print_help) {
2903 pymain_usage(0, config->program);
2904 return 1;
2905 }
2906
2907 if (cmdline->print_version) {
2908 printf("Python %s\n",
2909 (cmdline->print_version >= 2) ? Py_GetVersion() : PY_VERSION);
2910 return 1;
2911 }
2912
2913 /* For Py_GetArgcArgv(). Cleared by pymain_free(). */
2914 orig_argv = copy_wstrlist(pymain->argc, cmdline->argv);
2915 if (orig_argv == NULL) {
2916 pymain->err = _Py_INIT_NO_MEMORY();
2917 return -1;
2918 }
2919 orig_argc = pymain->argc;
2920
2921 _PyInitError err = config_init_warnoptions(config, cmdline);
2922 if (_Py_INIT_FAILED(err)) {
2923 pymain->err = err;
2924 return -1;
2925 }
2926 return 0;
2927 }
2928
2929
2930 /* Read the configuration into _PyCoreConfig and _PyMain, initialize the
2931 LC_CTYPE locale and Py_DecodeLocale().
2932
2933 Configuration:
2934
2935 * Command line arguments
2936 * Environment variables
2937 * Py_xxx global configuration variables
2938
2939 _PyCmdline is a temporary structure used to prioritize these
2940 variables. */
2941 static int
pymain_cmdline(_PyMain * pymain,_PyCoreConfig * config)2942 pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config)
2943 {
2944 /* Force default allocator, since pymain_free() and pymain_clear_config()
2945 must use the same allocator than this function. */
2946 PyMemAllocatorEx old_alloc;
2947 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2948 #ifdef Py_DEBUG
2949 PyMemAllocatorEx default_alloc;
2950 PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &default_alloc);
2951 #endif
2952
2953 _PyCmdline cmdline;
2954 memset(&cmdline, 0, sizeof(cmdline));
2955
2956 cmdline_get_global_config(&cmdline);
2957
2958 int res = pymain_cmdline_impl(pymain, config, &cmdline);
2959
2960 cmdline_set_global_config(&cmdline);
2961 _PyCoreConfig_SetGlobalConfig(config);
2962 if (Py_IsolatedFlag) {
2963 Py_IgnoreEnvironmentFlag = 1;
2964 Py_NoUserSiteDirectory = 1;
2965 }
2966
2967 pymain_clear_cmdline(pymain, &cmdline);
2968
2969 #ifdef Py_DEBUG
2970 /* Make sure that PYMEM_DOMAIN_RAW has not been modified */
2971 PyMemAllocatorEx cur_alloc;
2972 PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &cur_alloc);
2973 assert(memcmp(&cur_alloc, &default_alloc, sizeof(cur_alloc)) == 0);
2974 #endif
2975 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2976 return res;
2977 }
2978
2979
2980 static int
pymain_init(_PyMain * pymain)2981 pymain_init(_PyMain *pymain)
2982 {
2983 _PyCoreConfig local_config = _PyCoreConfig_INIT;
2984 _PyCoreConfig *config = &local_config;
2985
2986 /* 754 requires that FP exceptions run in "no stop" mode by default,
2987 * and until C vendors implement C99's ways to control FP exceptions,
2988 * Python requires non-stop mode. Alas, some platforms enable FP
2989 * exceptions by default. Here we disable them.
2990 */
2991 #ifdef __FreeBSD__
2992 fedisableexcept(FE_OVERFLOW);
2993 #endif
2994
2995 config->_disable_importlib = 0;
2996 config->install_signal_handlers = 1;
2997 _PyCoreConfig_GetGlobalConfig(config);
2998
2999 int res = pymain_cmdline(pymain, config);
3000 if (res < 0) {
3001 _Py_FatalInitError(pymain->err);
3002 }
3003 if (res == 1) {
3004 pymain_clear_config(&local_config);
3005 return res;
3006 }
3007
3008 pymain_init_stdio(pymain);
3009
3010 PyInterpreterState *interp;
3011 pymain->err = _Py_InitializeCore(&interp, config);
3012 if (_Py_INIT_FAILED(pymain->err)) {
3013 _Py_FatalInitError(pymain->err);
3014 }
3015
3016 pymain_clear_config(&local_config);
3017 config = &interp->core_config;
3018
3019 if (pymain_init_python_main(pymain, interp) < 0) {
3020 _Py_FatalInitError(pymain->err);
3021 }
3022
3023 if (pymain_init_sys_path(pymain, config) < 0) {
3024 _Py_FatalInitError(pymain->err);
3025 }
3026 return 0;
3027 }
3028
3029
3030 static int
pymain_main(_PyMain * pymain)3031 pymain_main(_PyMain *pymain)
3032 {
3033 int res = pymain_init(pymain);
3034 if (res == 1) {
3035 goto done;
3036 }
3037
3038 pymain_run_python(pymain);
3039
3040 if (Py_FinalizeEx() < 0) {
3041 /* Value unlikely to be confused with a non-error exit status or
3042 other special meaning */
3043 pymain->status = 120;
3044 }
3045
3046 done:
3047 pymain_free(pymain);
3048
3049 return pymain->status;
3050 }
3051
3052
3053 int
Py_Main(int argc,wchar_t ** argv)3054 Py_Main(int argc, wchar_t **argv)
3055 {
3056 _PyMain pymain = _PyMain_INIT;
3057 pymain.use_bytes_argv = 0;
3058 pymain.argc = argc;
3059 pymain.wchar_argv = argv;
3060
3061 return pymain_main(&pymain);
3062 }
3063
3064
3065 int
_Py_UnixMain(int argc,char ** argv)3066 _Py_UnixMain(int argc, char **argv)
3067 {
3068 _PyMain pymain = _PyMain_INIT;
3069 pymain.use_bytes_argv = 1;
3070 pymain.argc = argc;
3071 pymain.bytes_argv = argv;
3072
3073 return pymain_main(&pymain);
3074 }
3075
3076
3077 /* this is gonna seem *real weird*, but if you put some other code between
3078 Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
3079 while statement in Misc/gdbinit:ppystack */
3080
3081 /* Make the *original* argc/argv available to other modules.
3082 This is rare, but it is needed by the secureware extension. */
3083
3084 void
Py_GetArgcArgv(int * argc,wchar_t *** argv)3085 Py_GetArgcArgv(int *argc, wchar_t ***argv)
3086 {
3087 *argc = orig_argc;
3088 *argv = orig_argv;
3089 }
3090
3091 #ifdef __cplusplus
3092 }
3093 #endif
3094