blob: 00037d973d5dc598c481ef92bbc310061a96e040 [file] [log] [blame]
Victor Stinner6c785c02018-08-01 17:56:14 +02001#include "Python.h"
Victor Stinner6c785c02018-08-01 17:56:14 +02002#include "internal/pystate.h"
Victor Stinner5cb25892018-08-28 12:35:44 +02003#include <locale.h>
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02004#ifdef HAVE_LANGINFO_H
5# include <langinfo.h>
6#endif
Victor Stinner6c785c02018-08-01 17:56:14 +02007
8
9#define DECODE_LOCALE_ERR(NAME, LEN) \
10 (((LEN) == -2) \
11 ? _Py_INIT_USER_ERR("cannot decode " NAME) \
12 : _Py_INIT_NO_MEMORY())
13
14
15/* Global configuration variables */
16
17/* The default encoding used by the platform file system APIs
18 Can remain NULL for all platforms that don't have such a concept
19
20 Don't forget to modify PyUnicode_DecodeFSDefault() if you touch any of the
21 values for Py_FileSystemDefaultEncoding!
22*/
23#if defined(__APPLE__)
24const char *Py_FileSystemDefaultEncoding = "utf-8";
25int Py_HasFileSystemDefaultEncoding = 1;
26#elif defined(MS_WINDOWS)
27/* may be changed by initfsencoding(), but should never be free()d */
28const char *Py_FileSystemDefaultEncoding = "utf-8";
29int Py_HasFileSystemDefaultEncoding = 1;
30#else
31const char *Py_FileSystemDefaultEncoding = NULL; /* set by initfsencoding() */
32int Py_HasFileSystemDefaultEncoding = 0;
33#endif
34const char *Py_FileSystemDefaultEncodeErrors = "surrogateescape";
35/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
36 stdin and stdout error handler to "surrogateescape". It is equal to
37 -1 by default: unknown, will be set by Py_Main() */
38int Py_UTF8Mode = -1;
39int Py_DebugFlag = 0; /* Needed by parser.c */
40int Py_VerboseFlag = 0; /* Needed by import.c */
41int Py_QuietFlag = 0; /* Needed by sysmodule.c */
42int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
43int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
44int Py_OptimizeFlag = 0; /* Needed by compile.c */
45int Py_NoSiteFlag = 0; /* Suppress 'import site' */
46int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
47int Py_FrozenFlag = 0; /* Needed by getpath.c */
48int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
49int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
50int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
51int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
52int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
53int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
54#ifdef MS_WINDOWS
55int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
56int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
57#endif
Victor Stinner6c785c02018-08-01 17:56:14 +020058
59
60void
61_Py_wstrlist_clear(int len, wchar_t **list)
62{
63 for (int i=0; i < len; i++) {
64 PyMem_RawFree(list[i]);
65 }
66 PyMem_RawFree(list);
67}
68
69
70wchar_t**
71_Py_wstrlist_copy(int len, wchar_t **list)
72{
73 assert((len > 0 && list != NULL) || len == 0);
74 size_t size = len * sizeof(list[0]);
75 wchar_t **list_copy = PyMem_RawMalloc(size);
Alexey Izbysheveb746db2018-08-25 02:34:56 +030076 if (list_copy == NULL) {
77 return NULL;
78 }
Victor Stinner6c785c02018-08-01 17:56:14 +020079 for (int i=0; i < len; i++) {
80 wchar_t* arg = _PyMem_RawWcsdup(list[i]);
81 if (arg == NULL) {
Alexey Izbysheveb746db2018-08-25 02:34:56 +030082 _Py_wstrlist_clear(i, list_copy);
Victor Stinner6c785c02018-08-01 17:56:14 +020083 return NULL;
84 }
85 list_copy[i] = arg;
86 }
87 return list_copy;
88}
89
90
Victor Stinner124b9eb2018-08-29 01:29:06 +020091/* Helper to allow an embedding application to override the normal
92 * mechanism that attempts to figure out an appropriate IO encoding
93 */
94
Victor Stinnerdfe0dc72018-08-29 11:47:29 +020095static char *_Py_StandardStreamEncoding = NULL;
96static char *_Py_StandardStreamErrors = NULL;
Victor Stinner124b9eb2018-08-29 01:29:06 +020097
98int
99Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
100{
101 if (Py_IsInitialized()) {
102 /* This is too late to have any effect */
103 return -1;
104 }
105
106 int res = 0;
107
108 /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(),
109 but Py_Initialize() can change the allocator. Use a known allocator
110 to be able to release the memory later. */
111 PyMemAllocatorEx old_alloc;
112 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
113
114 /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
115 * initialised yet.
116 *
117 * However, the raw memory allocators are initialised appropriately
118 * as C static variables, so _PyMem_RawStrdup is OK even though
119 * Py_Initialize hasn't been called yet.
120 */
121 if (encoding) {
122 _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
123 if (!_Py_StandardStreamEncoding) {
124 res = -2;
125 goto done;
126 }
127 }
128 if (errors) {
129 _Py_StandardStreamErrors = _PyMem_RawStrdup(errors);
130 if (!_Py_StandardStreamErrors) {
131 if (_Py_StandardStreamEncoding) {
132 PyMem_RawFree(_Py_StandardStreamEncoding);
133 }
134 res = -3;
135 goto done;
136 }
137 }
138#ifdef MS_WINDOWS
139 if (_Py_StandardStreamEncoding) {
140 /* Overriding the stream encoding implies legacy streams */
141 Py_LegacyWindowsStdioFlag = 1;
142 }
143#endif
144
145done:
146 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
147
148 return res;
149}
150
151
152void
153_Py_ClearStandardStreamEncoding(void)
154{
155 /* Use the same allocator than Py_SetStandardStreamEncoding() */
156 PyMemAllocatorEx old_alloc;
157 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
158
159 /* We won't need them anymore. */
160 if (_Py_StandardStreamEncoding) {
161 PyMem_RawFree(_Py_StandardStreamEncoding);
162 _Py_StandardStreamEncoding = NULL;
163 }
164 if (_Py_StandardStreamErrors) {
165 PyMem_RawFree(_Py_StandardStreamErrors);
166 _Py_StandardStreamErrors = NULL;
167 }
168
169 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
170}
171
172
Victor Stinner6c785c02018-08-01 17:56:14 +0200173/* Free memory allocated in config, but don't clear all attributes */
174void
175_PyCoreConfig_Clear(_PyCoreConfig *config)
176{
177#define CLEAR(ATTR) \
178 do { \
179 PyMem_RawFree(ATTR); \
180 ATTR = NULL; \
181 } while (0)
182#define CLEAR_WSTRLIST(LEN, LIST) \
183 do { \
184 _Py_wstrlist_clear(LEN, LIST); \
185 LEN = 0; \
186 LIST = NULL; \
187 } while (0)
188
189 CLEAR(config->pycache_prefix);
190 CLEAR(config->module_search_path_env);
191 CLEAR(config->home);
192 CLEAR(config->program_name);
193 CLEAR(config->program);
194
195 CLEAR_WSTRLIST(config->argc, config->argv);
196 config->argc = -1;
197
198 CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions);
199 CLEAR_WSTRLIST(config->nxoption, config->xoptions);
200 CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths);
201 config->nmodule_search_path = -1;
202
203 CLEAR(config->executable);
204 CLEAR(config->prefix);
205 CLEAR(config->base_prefix);
206 CLEAR(config->exec_prefix);
207#ifdef MS_WINDOWS
208 CLEAR(config->dll_path);
209#endif
210 CLEAR(config->base_exec_prefix);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200211
212 CLEAR(config->stdio_encoding);
213 CLEAR(config->stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200214#undef CLEAR
215#undef CLEAR_WSTRLIST
216}
217
218
219int
220_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
221{
222 _PyCoreConfig_Clear(config);
223
224#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200225#define COPY_STR_ATTR(ATTR) \
226 do { \
227 if (config2->ATTR != NULL) { \
228 config->ATTR = _PyMem_RawStrdup(config2->ATTR); \
229 if (config->ATTR == NULL) { \
230 return -1; \
231 } \
232 } \
233 } while (0)
Victor Stinner124b9eb2018-08-29 01:29:06 +0200234#define COPY_WSTR_ATTR(ATTR) \
Victor Stinner6c785c02018-08-01 17:56:14 +0200235 do { \
236 if (config2->ATTR != NULL) { \
237 config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
238 if (config->ATTR == NULL) { \
239 return -1; \
240 } \
241 } \
242 } while (0)
243#define COPY_WSTRLIST(LEN, LIST) \
244 do { \
245 if (config2->LIST != NULL) { \
246 config->LIST = _Py_wstrlist_copy(config2->LEN, config2->LIST); \
247 if (config->LIST == NULL) { \
248 return -1; \
249 } \
250 } \
251 config->LEN = config2->LEN; \
252 } while (0)
253
254 COPY_ATTR(install_signal_handlers);
255 COPY_ATTR(use_environment);
256 COPY_ATTR(use_hash_seed);
257 COPY_ATTR(hash_seed);
258 COPY_ATTR(_install_importlib);
259 COPY_ATTR(allocator);
260 COPY_ATTR(dev_mode);
261 COPY_ATTR(faulthandler);
262 COPY_ATTR(tracemalloc);
263 COPY_ATTR(import_time);
264 COPY_ATTR(show_ref_count);
265 COPY_ATTR(show_alloc_count);
266 COPY_ATTR(dump_refs);
267 COPY_ATTR(malloc_stats);
268
269 COPY_ATTR(coerce_c_locale);
270 COPY_ATTR(coerce_c_locale_warn);
271 COPY_ATTR(utf8_mode);
272
Victor Stinner124b9eb2018-08-29 01:29:06 +0200273 COPY_WSTR_ATTR(pycache_prefix);
274 COPY_WSTR_ATTR(module_search_path_env);
275 COPY_WSTR_ATTR(home);
276 COPY_WSTR_ATTR(program_name);
277 COPY_WSTR_ATTR(program);
Victor Stinner6c785c02018-08-01 17:56:14 +0200278
279 COPY_WSTRLIST(argc, argv);
280 COPY_WSTRLIST(nwarnoption, warnoptions);
281 COPY_WSTRLIST(nxoption, xoptions);
282 COPY_WSTRLIST(nmodule_search_path, module_search_paths);
283
Victor Stinner124b9eb2018-08-29 01:29:06 +0200284 COPY_WSTR_ATTR(executable);
285 COPY_WSTR_ATTR(prefix);
286 COPY_WSTR_ATTR(base_prefix);
287 COPY_WSTR_ATTR(exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200288#ifdef MS_WINDOWS
Victor Stinner124b9eb2018-08-29 01:29:06 +0200289 COPY_WSTR_ATTR(dll_path);
Victor Stinner6c785c02018-08-01 17:56:14 +0200290#endif
Victor Stinner124b9eb2018-08-29 01:29:06 +0200291 COPY_WSTR_ATTR(base_exec_prefix);
Victor Stinner6c785c02018-08-01 17:56:14 +0200292
293 COPY_ATTR(isolated);
294 COPY_ATTR(site_import);
295 COPY_ATTR(bytes_warning);
296 COPY_ATTR(inspect);
297 COPY_ATTR(interactive);
298 COPY_ATTR(optimization_level);
299 COPY_ATTR(parser_debug);
300 COPY_ATTR(write_bytecode);
301 COPY_ATTR(verbose);
302 COPY_ATTR(quiet);
303 COPY_ATTR(user_site_directory);
304 COPY_ATTR(buffered_stdio);
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200305 COPY_STR_ATTR(stdio_encoding);
306 COPY_STR_ATTR(stdio_errors);
Victor Stinner6c785c02018-08-01 17:56:14 +0200307#ifdef MS_WINDOWS
308 COPY_ATTR(legacy_windows_fs_encoding);
309 COPY_ATTR(legacy_windows_stdio);
310#endif
311 COPY_ATTR(_check_hash_pycs_mode);
312 COPY_ATTR(_frozen);
313
314#undef COPY_ATTR
Victor Stinner124b9eb2018-08-29 01:29:06 +0200315#undef COPY_WSTR_ATTR
Victor Stinner6c785c02018-08-01 17:56:14 +0200316#undef COPY_WSTRLIST
317 return 0;
318}
319
320
321const char*
322_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
323{
324 assert(config->use_environment >= 0);
325
326 if (!config->use_environment) {
327 return NULL;
328 }
329
330 const char *var = getenv(name);
331 if (var && var[0] != '\0') {
332 return var;
333 }
334 else {
335 return NULL;
336 }
337}
338
339
340int
341_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
342 wchar_t **dest,
343 wchar_t *wname, char *name)
344{
345 assert(config->use_environment >= 0);
346
347 if (!config->use_environment) {
348 *dest = NULL;
349 return 0;
350 }
351
352#ifdef MS_WINDOWS
353 const wchar_t *var = _wgetenv(wname);
354 if (!var || var[0] == '\0') {
355 *dest = NULL;
356 return 0;
357 }
358
359 wchar_t *copy = _PyMem_RawWcsdup(var);
360 if (copy == NULL) {
361 return -1;
362 }
363
364 *dest = copy;
365#else
366 const char *var = getenv(name);
367 if (!var || var[0] == '\0') {
368 *dest = NULL;
369 return 0;
370 }
371
372 size_t len;
373 wchar_t *wvar = Py_DecodeLocale(var, &len);
374 if (!wvar) {
375 if (len == (size_t)-2) {
376 return -2;
377 }
378 else {
379 return -1;
380 }
381 }
382 *dest = wvar;
383#endif
384 return 0;
385}
386
387
388void
389_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
390{
391#define COPY_FLAG(ATTR, VALUE) \
392 if (config->ATTR == -1) { \
393 config->ATTR = VALUE; \
394 }
395#define COPY_NOT_FLAG(ATTR, VALUE) \
396 if (config->ATTR == -1) { \
397 config->ATTR = !(VALUE); \
398 }
399
400 COPY_FLAG(utf8_mode, Py_UTF8Mode);
401 COPY_FLAG(isolated, Py_IsolatedFlag);
402 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
403 COPY_FLAG(inspect, Py_InspectFlag);
404 COPY_FLAG(interactive, Py_InteractiveFlag);
405 COPY_FLAG(optimization_level, Py_OptimizeFlag);
406 COPY_FLAG(parser_debug, Py_DebugFlag);
407 COPY_FLAG(verbose, Py_VerboseFlag);
408 COPY_FLAG(quiet, Py_QuietFlag);
409#ifdef MS_WINDOWS
410 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
411 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
412#endif
413 COPY_FLAG(_frozen, Py_FrozenFlag);
414
415 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
416 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
417 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
418 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
419 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
420
Victor Stinner6c785c02018-08-01 17:56:14 +0200421#undef COPY_FLAG
422#undef COPY_NOT_FLAG
423}
424
425
426/* Set Py_xxx global configuration variables from 'config' configuration. */
427void
428_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
429{
430#define COPY_FLAG(ATTR, VAR) \
431 if (config->ATTR != -1) { \
432 VAR = config->ATTR; \
433 }
434#define COPY_NOT_FLAG(ATTR, VAR) \
435 if (config->ATTR != -1) { \
436 VAR = !config->ATTR; \
437 }
438
439 COPY_FLAG(utf8_mode, Py_UTF8Mode);
440 COPY_FLAG(isolated, Py_IsolatedFlag);
441 COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
442 COPY_FLAG(inspect, Py_InspectFlag);
443 COPY_FLAG(interactive, Py_InteractiveFlag);
444 COPY_FLAG(optimization_level, Py_OptimizeFlag);
445 COPY_FLAG(parser_debug, Py_DebugFlag);
446 COPY_FLAG(verbose, Py_VerboseFlag);
447 COPY_FLAG(quiet, Py_QuietFlag);
448#ifdef MS_WINDOWS
449 COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
450 COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
451#endif
452
453 COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
454 COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
455 COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
456 COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
457 COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
458
Victor Stinner6c785c02018-08-01 17:56:14 +0200459 /* Random or non-zero hash seed */
460 Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
461 config->hash_seed != 0);
462
463#undef COPY_FLAG
464#undef COPY_NOT_FLAG
465}
466
467
468/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
469 environment variables on macOS if available. */
470static _PyInitError
471config_init_program_name(_PyCoreConfig *config)
472{
Victor Stinner5a953fd2018-08-03 22:49:07 +0200473 assert(config->program_name == NULL);
474
Victor Stinner6c785c02018-08-01 17:56:14 +0200475 /* If Py_SetProgramName() was called, use its value */
476 const wchar_t *program_name = _Py_path_config.program_name;
477 if (program_name != NULL) {
478 config->program_name = _PyMem_RawWcsdup(program_name);
479 if (config->program_name == NULL) {
480 return _Py_INIT_NO_MEMORY();
481 }
482 return _Py_INIT_OK();
483 }
484
485#ifdef __APPLE__
486 /* On MacOS X, when the Python interpreter is embedded in an
487 application bundle, it gets executed by a bootstrapping script
488 that does os.execve() with an argv[0] that's different from the
489 actual Python executable. This is needed to keep the Finder happy,
490 or rather, to work around Apple's overly strict requirements of
491 the process name. However, we still need a usable sys.executable,
492 so the actual executable path is passed in an environment variable.
493 See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
494 script. */
495 const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
496 if (p != NULL) {
497 size_t len;
498 wchar_t* program_name = Py_DecodeLocale(p, &len);
499 if (program_name == NULL) {
500 return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment "
501 "variable", (Py_ssize_t)len);
502 }
503 config->program_name = program_name;
504 return _Py_INIT_OK();
505 }
506#ifdef WITH_NEXT_FRAMEWORK
507 else {
508 const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
509 if (pyvenv_launcher && *pyvenv_launcher) {
510 /* Used by Mac/Tools/pythonw.c to forward
511 * the argv0 of the stub executable
512 */
513 size_t len;
514 wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len);
515 if (program_name == NULL) {
516 return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment "
517 "variable", (Py_ssize_t)len);
518 }
519 config->program_name = program_name;
520 return _Py_INIT_OK();
521 }
522 }
523#endif /* WITH_NEXT_FRAMEWORK */
524#endif /* __APPLE__ */
525
526 /* Use argv[0] by default, if available */
527 if (config->program != NULL) {
528 config->program_name = _PyMem_RawWcsdup(config->program);
529 if (config->program_name == NULL) {
530 return _Py_INIT_NO_MEMORY();
531 }
532 return _Py_INIT_OK();
533 }
534
535 /* Last fall back: hardcoded string */
536#ifdef MS_WINDOWS
537 const wchar_t *default_program_name = L"python";
538#else
539 const wchar_t *default_program_name = L"python3";
540#endif
541 config->program_name = _PyMem_RawWcsdup(default_program_name);
542 if (config->program_name == NULL) {
543 return _Py_INIT_NO_MEMORY();
544 }
545 return _Py_INIT_OK();
546}
547
548
549static const wchar_t*
550config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
551{
552 int nxoption = config->nxoption;
553 wchar_t **xoptions = config->xoptions;
554 for (int i=0; i < nxoption; i++) {
555 wchar_t *option = xoptions[i];
556 size_t len;
557 wchar_t *sep = wcschr(option, L'=');
558 if (sep != NULL) {
559 len = (sep - option);
560 }
561 else {
562 len = wcslen(option);
563 }
564 if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') {
565 return option;
566 }
567 }
568 return NULL;
569}
570
571
572static _PyInitError
573config_init_home(_PyCoreConfig *config)
574{
575 wchar_t *home;
576
577 /* If Py_SetPythonHome() was called, use its value */
578 home = _Py_path_config.home;
579 if (home) {
580 config->home = _PyMem_RawWcsdup(home);
581 if (config->home == NULL) {
582 return _Py_INIT_NO_MEMORY();
583 }
584 return _Py_INIT_OK();
585 }
586
587 int res = _PyCoreConfig_GetEnvDup(config, &home,
588 L"PYTHONHOME", "PYTHONHOME");
589 if (res < 0) {
590 return DECODE_LOCALE_ERR("PYTHONHOME", res);
591 }
592 config->home = home;
593 return _Py_INIT_OK();
594}
595
596
597static _PyInitError
598config_init_hash_seed(_PyCoreConfig *config)
599{
600 const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED");
601
602 Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
603 /* Convert a text seed to a numeric one */
604 if (seed_text && strcmp(seed_text, "random") != 0) {
605 const char *endptr = seed_text;
606 unsigned long seed;
607 errno = 0;
608 seed = strtoul(seed_text, (char **)&endptr, 10);
609 if (*endptr != '\0'
610 || seed > 4294967295UL
611 || (errno == ERANGE && seed == ULONG_MAX))
612 {
613 return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" "
614 "or an integer in range [0; 4294967295]");
615 }
616 /* Use a specific hash */
617 config->use_hash_seed = 1;
618 config->hash_seed = seed;
619 }
620 else {
621 /* Use a random hash */
622 config->use_hash_seed = 0;
623 config->hash_seed = 0;
624 }
625 return _Py_INIT_OK();
626}
627
628
629static _PyInitError
630config_init_utf8_mode(_PyCoreConfig *config)
631{
632 const wchar_t *xopt = config_get_xoption(config, L"utf8");
633 if (xopt) {
634 wchar_t *sep = wcschr(xopt, L'=');
635 if (sep) {
636 xopt = sep + 1;
637 if (wcscmp(xopt, L"1") == 0) {
638 config->utf8_mode = 1;
639 }
640 else if (wcscmp(xopt, L"0") == 0) {
641 config->utf8_mode = 0;
642 }
643 else {
644 return _Py_INIT_USER_ERR("invalid -X utf8 option value");
645 }
646 }
647 else {
648 config->utf8_mode = 1;
649 }
650 return _Py_INIT_OK();
651 }
652
653 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONUTF8");
654 if (opt) {
655 if (strcmp(opt, "1") == 0) {
656 config->utf8_mode = 1;
657 }
658 else if (strcmp(opt, "0") == 0) {
659 config->utf8_mode = 0;
660 }
661 else {
662 return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
663 "variable value");
664 }
665 return _Py_INIT_OK();
666 }
667
668 return _Py_INIT_OK();
669}
670
671
672static int
673config_str_to_int(const char *str, int *result)
674{
675 const char *endptr = str;
676 errno = 0;
677 long value = strtol(str, (char **)&endptr, 10);
678 if (*endptr != '\0' || errno == ERANGE) {
679 return -1;
680 }
681 if (value < INT_MIN || value > INT_MAX) {
682 return -1;
683 }
684
685 *result = (int)value;
686 return 0;
687}
688
689
690static int
691config_wstr_to_int(const wchar_t *wstr, int *result)
692{
693 const wchar_t *endptr = wstr;
694 errno = 0;
695 long value = wcstol(wstr, (wchar_t **)&endptr, 10);
696 if (*endptr != '\0' || errno == ERANGE) {
697 return -1;
698 }
699 if (value < INT_MIN || value > INT_MAX) {
700 return -1;
701 }
702
703 *result = (int)value;
704 return 0;
705}
706
707
708static void
709get_env_flag(_PyCoreConfig *config, int *flag, const char *name)
710{
711 const char *var = _PyCoreConfig_GetEnv(config, name);
712 if (!var) {
713 return;
714 }
715 int value;
716 if (config_str_to_int(var, &value) < 0 || value < 0) {
717 /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */
718 value = 1;
719 }
720 if (*flag < value) {
721 *flag = value;
722 }
723}
724
725
726static _PyInitError
727config_read_env_vars(_PyCoreConfig *config)
728{
Victor Stinner6c785c02018-08-01 17:56:14 +0200729 /* Get environment variables */
730 get_env_flag(config, &config->parser_debug, "PYTHONDEBUG");
731 get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
732 get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
733 get_env_flag(config, &config->inspect, "PYTHONINSPECT");
734
735 int dont_write_bytecode = 0;
736 get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
737 if (dont_write_bytecode) {
738 config->write_bytecode = 0;
739 }
740
741 int no_user_site_directory = 0;
742 get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE");
743 if (no_user_site_directory) {
744 config->user_site_directory = 0;
745 }
746
747 int unbuffered_stdio = 0;
748 get_env_flag(config, &unbuffered_stdio, "PYTHONUNBUFFERED");
749 if (unbuffered_stdio) {
750 config->buffered_stdio = 0;
751 }
752
753#ifdef MS_WINDOWS
754 get_env_flag(config, &config->legacy_windows_fs_encoding,
755 "PYTHONLEGACYWINDOWSFSENCODING");
756 get_env_flag(config, &config->legacy_windows_stdio,
757 "PYTHONLEGACYWINDOWSSTDIO");
758#endif
759
760 if (config->allocator == NULL) {
761 config->allocator = _PyCoreConfig_GetEnv(config, "PYTHONMALLOC");
762 }
763
764 if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
765 config->dump_refs = 1;
766 }
767 if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) {
768 config->malloc_stats = 1;
769 }
770
Victor Stinner2c8ddcf2018-08-29 00:16:53 +0200771 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE");
772 if (env) {
773 if (strcmp(env, "0") == 0) {
774 if (config->coerce_c_locale < 0) {
Victor Stinner5a953fd2018-08-03 22:49:07 +0200775 config->coerce_c_locale = 0;
776 }
Victor Stinner2c8ddcf2018-08-29 00:16:53 +0200777 }
778 else if (strcmp(env, "warn") == 0) {
779 config->coerce_c_locale_warn = 1;
780 }
781 else {
782 if (config->coerce_c_locale < 0) {
Victor Stinner5a953fd2018-08-03 22:49:07 +0200783 config->coerce_c_locale = 1;
784 }
Victor Stinner6c785c02018-08-01 17:56:14 +0200785 }
786 }
787
788 wchar_t *path;
789 int res = _PyCoreConfig_GetEnvDup(config, &path,
790 L"PYTHONPATH", "PYTHONPATH");
791 if (res < 0) {
792 return DECODE_LOCALE_ERR("PYTHONPATH", res);
793 }
794 config->module_search_path_env = path;
795
796 if (config->use_hash_seed < 0) {
797 _PyInitError err = config_init_hash_seed(config);
798 if (_Py_INIT_FAILED(err)) {
799 return err;
800 }
801 }
802
803 return _Py_INIT_OK();
804}
805
806
807static _PyInitError
808config_init_tracemalloc(_PyCoreConfig *config)
809{
810 int nframe;
811 int valid;
812
813 const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC");
814 if (env) {
815 if (!config_str_to_int(env, &nframe)) {
816 valid = (nframe >= 0);
817 }
818 else {
819 valid = 0;
820 }
821 if (!valid) {
822 return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
823 "of frames");
824 }
825 config->tracemalloc = nframe;
826 }
827
828 const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
829 if (xoption) {
830 const wchar_t *sep = wcschr(xoption, L'=');
831 if (sep) {
832 if (!config_wstr_to_int(sep + 1, &nframe)) {
833 valid = (nframe >= 0);
834 }
835 else {
836 valid = 0;
837 }
838 if (!valid) {
839 return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
840 "invalid number of frames");
841 }
842 }
843 else {
844 /* -X tracemalloc behaves as -X tracemalloc=1 */
845 nframe = 1;
846 }
847 config->tracemalloc = nframe;
848 }
849 return _Py_INIT_OK();
850}
851
852
853static _PyInitError
854config_init_pycache_prefix(_PyCoreConfig *config)
855{
856 assert(config->pycache_prefix == NULL);
857
858 const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix");
859 if (xoption) {
860 const wchar_t *sep = wcschr(xoption, L'=');
861 if (sep && wcslen(sep) > 1) {
862 config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
863 if (config->pycache_prefix == NULL) {
864 return _Py_INIT_NO_MEMORY();
865 }
866 }
867 else {
868 // -X pycache_prefix= can cancel the env var
869 config->pycache_prefix = NULL;
870 }
871 }
872 else {
873 wchar_t *env;
874 int res = _PyCoreConfig_GetEnvDup(config, &env,
875 L"PYTHONPYCACHEPREFIX",
876 "PYTHONPYCACHEPREFIX");
877 if (res < 0) {
878 return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res);
879 }
880
881 if (env) {
882 config->pycache_prefix = env;
883 }
884 }
885 return _Py_INIT_OK();
886}
887
888
889static _PyInitError
890config_read_complex_options(_PyCoreConfig *config)
891{
892 /* More complex options configured by env var and -X option */
893 if (config->faulthandler < 0) {
894 if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER")
895 || config_get_xoption(config, L"faulthandler")) {
896 config->faulthandler = 1;
897 }
898 }
899 if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME")
900 || config_get_xoption(config, L"importtime")) {
901 config->import_time = 1;
902 }
903 if (config_get_xoption(config, L"dev" ) ||
904 _PyCoreConfig_GetEnv(config, "PYTHONDEVMODE"))
905 {
906 config->dev_mode = 1;
907 }
908
909 _PyInitError err;
910 if (config->tracemalloc < 0) {
911 err = config_init_tracemalloc(config);
912 if (_Py_INIT_FAILED(err)) {
913 return err;
914 }
915 }
916
917 if (config->pycache_prefix == NULL) {
918 err = config_init_pycache_prefix(config);
919 if (_Py_INIT_FAILED(err)) {
920 return err;
921 }
922 }
923 return _Py_INIT_OK();
924}
925
926
927static void
928config_init_locale(_PyCoreConfig *config)
929{
Victor Stinnerd500e532018-08-28 17:27:36 +0200930 if (config->coerce_c_locale < 0) {
Victor Stinner5cb25892018-08-28 12:35:44 +0200931 /* The C locale enables the C locale coercion (PEP 538) */
Victor Stinnerd500e532018-08-28 17:27:36 +0200932 if (_Py_LegacyLocaleDetected()) {
Victor Stinner6c785c02018-08-01 17:56:14 +0200933 config->coerce_c_locale = 1;
934 }
Victor Stinner6c785c02018-08-01 17:56:14 +0200935 }
Victor Stinnerd500e532018-08-28 17:27:36 +0200936
Victor Stinner5cb25892018-08-28 12:35:44 +0200937#ifndef MS_WINDOWS
Victor Stinnerd500e532018-08-28 17:27:36 +0200938 if (config->utf8_mode < 0) {
Victor Stinner5cb25892018-08-28 12:35:44 +0200939 /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */
Victor Stinnerd500e532018-08-28 17:27:36 +0200940 const char *ctype_loc = setlocale(LC_CTYPE, NULL);
941 if (ctype_loc != NULL
942 && (strcmp(ctype_loc, "C") == 0
943 || strcmp(ctype_loc, "POSIX") == 0))
944 {
Victor Stinner5cb25892018-08-28 12:35:44 +0200945 config->utf8_mode = 1;
946 }
947 }
948#endif
Victor Stinner6c785c02018-08-01 17:56:14 +0200949}
950
951
Victor Stinnerdfe0dc72018-08-29 11:47:29 +0200952static const char *
953get_stdio_errors(const _PyCoreConfig *config)
954{
955#ifndef MS_WINDOWS
956 const char *loc = setlocale(LC_CTYPE, NULL);
957 if (loc != NULL) {
958 /* surrogateescape is the default in the legacy C and POSIX locales */
959 if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) {
960 return "surrogateescape";
961 }
962
963#ifdef PY_COERCE_C_LOCALE
964 /* surrogateescape is the default in locale coercion target locales */
965 if (_Py_IsLocaleCoercionTarget(loc)) {
966 return "surrogateescape";
967 }
968#endif
969 }
970
971 return "strict";
972#else
973 /* On Windows, always use surrogateescape by default */
974 return "surrogateescape";
975#endif
976}
977
978
979_PyInitError
980_Py_get_locale_encoding(char **locale_encoding)
981{
982#ifdef MS_WINDOWS
983 char encoding[20];
984 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
985#elif defined(__ANDROID__)
986 const char *encoding = "UTF-8";
987#else
988 const char *encoding = nl_langinfo(CODESET);
989 if (!encoding || encoding[0] == '\0') {
990 return _Py_INIT_USER_ERR("failed to get the locale encoding: "
991 "nl_langinfo(CODESET) failed");
992 }
993#endif
994 *locale_encoding = _PyMem_RawStrdup(encoding);
995 if (*locale_encoding == NULL) {
996 return _Py_INIT_NO_MEMORY();
997 }
998 return _Py_INIT_OK();
999}
1000
1001
1002static _PyInitError
1003config_init_stdio_encoding(_PyCoreConfig *config)
1004{
1005 /* If Py_SetStandardStreamEncoding() have been called, use these
1006 parameters. */
1007 if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
1008 config->stdio_encoding = _PyMem_RawStrdup(_Py_StandardStreamEncoding);
1009 if (config->stdio_encoding == NULL) {
1010 return _Py_INIT_NO_MEMORY();
1011 }
1012 }
1013
1014 if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
1015 config->stdio_errors = _PyMem_RawStrdup(_Py_StandardStreamErrors);
1016 if (config->stdio_errors == NULL) {
1017 return _Py_INIT_NO_MEMORY();
1018 }
1019 }
1020
1021 if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
1022 return _Py_INIT_OK();
1023 }
1024
1025 /* PYTHONIOENCODING environment variable */
1026 const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
1027 if (opt) {
1028 char *pythonioencoding = _PyMem_RawStrdup(opt);
1029 if (pythonioencoding == NULL) {
1030 return _Py_INIT_NO_MEMORY();
1031 }
1032
1033 char *err = strchr(pythonioencoding, ':');
1034 if (err) {
1035 *err = '\0';
1036 err++;
1037 if (!err[0]) {
1038 err = NULL;
1039 }
1040 }
1041
1042 /* Does PYTHONIOENCODING contain an encoding? */
1043 if (pythonioencoding[0]) {
1044 if (config->stdio_encoding == NULL) {
1045 config->stdio_encoding = _PyMem_RawStrdup(pythonioencoding);
1046 if (config->stdio_encoding == NULL) {
1047 PyMem_RawFree(pythonioencoding);
1048 return _Py_INIT_NO_MEMORY();
1049 }
1050 }
1051
1052 /* If the encoding is set but not the error handler,
1053 use "strict" error handler by default.
1054 PYTHONIOENCODING=latin1 behaves as
1055 PYTHONIOENCODING=latin1:strict. */
1056 if (!err) {
1057 err = "strict";
1058 }
1059 }
1060
1061 if (config->stdio_errors == NULL && err != NULL) {
1062 config->stdio_errors = _PyMem_RawStrdup(err);
1063 if (config->stdio_errors == NULL) {
1064 PyMem_RawFree(pythonioencoding);
1065 return _Py_INIT_NO_MEMORY();
1066 }
1067 }
1068
1069 PyMem_RawFree(pythonioencoding);
1070 }
1071
1072 /* UTF-8 Mode uses UTF-8/surrogateescape */
1073 if (config->utf8_mode) {
1074 if (config->stdio_encoding == NULL) {
1075 config->stdio_encoding = _PyMem_RawStrdup("utf-8");
1076 if (config->stdio_encoding == NULL) {
1077 return _Py_INIT_NO_MEMORY();
1078 }
1079 }
1080 if (config->stdio_errors == NULL) {
1081 config->stdio_errors = _PyMem_RawStrdup("surrogateescape");
1082 if (config->stdio_errors == NULL) {
1083 return _Py_INIT_NO_MEMORY();
1084 }
1085 }
1086 }
1087
1088 /* Choose the default error handler based on the current locale. */
1089 if (config->stdio_encoding == NULL) {
1090 _PyInitError err = _Py_get_locale_encoding(&config->stdio_encoding);
1091 if (_Py_INIT_FAILED(err)) {
1092 return err;
1093 }
1094 }
1095 if (config->stdio_errors == NULL) {
1096 const char *errors = get_stdio_errors(config);
1097 config->stdio_errors = _PyMem_RawStrdup(errors);
1098 if (config->stdio_errors == NULL) {
1099 return _Py_INIT_NO_MEMORY();
1100 }
1101 }
1102
1103 return _Py_INIT_OK();
1104}
1105
1106
Victor Stinner6c785c02018-08-01 17:56:14 +02001107/* Read configuration settings from standard locations
1108 *
1109 * This function doesn't make any changes to the interpreter state - it
1110 * merely populates any missing configuration settings. This allows an
1111 * embedding application to completely override a config option by
1112 * setting it before calling this function, or else modify the default
1113 * setting before passing the fully populated config to Py_EndInitialization.
1114 *
1115 * More advanced selective initialization tricks are possible by calling
1116 * this function multiple times with various preconfigured settings.
1117 */
1118
1119_PyInitError
1120_PyCoreConfig_Read(_PyCoreConfig *config)
1121{
1122 _PyInitError err;
1123
1124 _PyCoreConfig_GetGlobalConfig(config);
Victor Stinner124b9eb2018-08-29 01:29:06 +02001125 assert(config->use_environment >= 0);
Victor Stinner6c785c02018-08-01 17:56:14 +02001126
1127 if (config->isolated > 0) {
1128 config->use_environment = 0;
1129 config->user_site_directory = 0;
1130 }
1131
1132#ifdef MS_WINDOWS
1133 if (config->legacy_windows_fs_encoding) {
1134 config->utf8_mode = 0;
1135 }
1136#endif
1137
Victor Stinner6c785c02018-08-01 17:56:14 +02001138 if (config->use_environment) {
1139 err = config_read_env_vars(config);
1140 if (_Py_INIT_FAILED(err)) {
1141 return err;
1142 }
1143 }
1144
1145 /* -X options */
1146 if (config_get_xoption(config, L"showrefcount")) {
1147 config->show_ref_count = 1;
1148 }
1149 if (config_get_xoption(config, L"showalloccount")) {
1150 config->show_alloc_count = 1;
1151 }
1152
1153 err = config_read_complex_options(config);
1154 if (_Py_INIT_FAILED(err)) {
1155 return err;
1156 }
1157
1158 if (config->utf8_mode < 0) {
1159 err = config_init_utf8_mode(config);
1160 if (_Py_INIT_FAILED(err)) {
1161 return err;
1162 }
1163 }
1164
1165 if (config->home == NULL) {
1166 err = config_init_home(config);
1167 if (_Py_INIT_FAILED(err)) {
1168 return err;
1169 }
1170 }
1171
1172 if (config->program_name == NULL) {
1173 err = config_init_program_name(config);
1174 if (_Py_INIT_FAILED(err)) {
1175 return err;
1176 }
1177 }
1178
Victor Stinner5a953fd2018-08-03 22:49:07 +02001179 if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
1180 config_init_locale(config);
1181 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001182
1183 if (config->_install_importlib) {
1184 err = _PyCoreConfig_InitPathConfig(config);
1185 if (_Py_INIT_FAILED(err)) {
1186 return err;
1187 }
1188 }
1189
1190 /* default values */
1191 if (config->dev_mode) {
1192 if (config->faulthandler < 0) {
1193 config->faulthandler = 1;
1194 }
1195 if (config->allocator == NULL) {
1196 config->allocator = "debug";
1197 }
1198 }
1199 if (config->use_hash_seed < 0) {
1200 config->use_hash_seed = 0;
1201 config->hash_seed = 0;
1202 }
1203 if (config->faulthandler < 0) {
1204 config->faulthandler = 0;
1205 }
1206 if (config->tracemalloc < 0) {
1207 config->tracemalloc = 0;
1208 }
1209 if (config->coerce_c_locale < 0) {
1210 config->coerce_c_locale = 0;
1211 }
1212 if (config->utf8_mode < 0) {
1213 config->utf8_mode = 0;
1214 }
Victor Stinner6c785c02018-08-01 17:56:14 +02001215 if (config->argc < 0) {
1216 config->argc = 0;
1217 }
1218
Victor Stinnerdfe0dc72018-08-29 11:47:29 +02001219 err = config_init_stdio_encoding(config);
1220 if (_Py_INIT_FAILED(err)) {
1221 return err;
1222 }
1223
Victor Stinner124b9eb2018-08-29 01:29:06 +02001224 assert(config->coerce_c_locale >= 0);
1225 assert(config->use_environment >= 0);
1226
Victor Stinner6c785c02018-08-01 17:56:14 +02001227 return _Py_INIT_OK();
1228}