comparison Python/pythonrun.c @ 61593:47b4da86b9b9

Issue #8610: Load file system codec at startup, and display a fatal error on failure. Set the file system encoding to utf-8 (instead of None) if getting the locale encoding failed, or if nl_langinfo(CODESET) function is missing.
author Victor Stinner <victor.stinner@haypocalc.com>
date Sat, 15 May 2010 12:27:16 +0000
parents 9e5b73ea6a7c
children f3f95ed82744
comparison
equal deleted inserted replaced
61591:d972d052ee22 61593:47b4da86b9b9
55 55
56 extern grammar _PyParser_Grammar; /* From graminit.c */ 56 extern grammar _PyParser_Grammar; /* From graminit.c */
57 57
58 /* Forward */ 58 /* Forward */
59 static void initmain(void); 59 static void initmain(void);
60 static void initfsencoding(void);
60 static void initsite(void); 61 static void initsite(void);
61 static int initstdio(void); 62 static int initstdio(void);
62 static void flush_io(void); 63 static void flush_io(void);
63 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, 64 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
64 PyCompilerFlags *, PyArena *); 65 PyCompilerFlags *, PyArena *);
157 Py_DECREF(name); 158 Py_DECREF(name);
158 return codeset; 159 return codeset;
159 160
160 error: 161 error:
161 Py_XDECREF(codec); 162 Py_XDECREF(codec);
162 PyErr_Clear();
163 return NULL; 163 return NULL;
164 } 164 }
165 #endif 165 #endif
166 166
167 void 167 void
169 { 169 {
170 PyInterpreterState *interp; 170 PyInterpreterState *interp;
171 PyThreadState *tstate; 171 PyThreadState *tstate;
172 PyObject *bimod, *sysmod, *pstderr; 172 PyObject *bimod, *sysmod, *pstderr;
173 char *p; 173 char *p;
174 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
175 char *codeset;
176 #endif
177 extern void _Py_ReadyTypes(void); 174 extern void _Py_ReadyTypes(void);
178 175
179 if (initialized) 176 if (initialized)
180 return; 177 return;
181 initialized = 1; 178 initialized = 1;
262 259
263 _PyImport_Init(); 260 _PyImport_Init();
264 261
265 _PyImportHooks_Init(); 262 _PyImportHooks_Init();
266 263
267 #if defined(HAVE_LANGINFO_H) && defined(CODESET) 264 initfsencoding();
268 /* On Unix, set the file system encoding according to the
269 user's preference, if the CODESET names a well-known
270 Python codec, and Py_FileSystemDefaultEncoding isn't
271 initialized by other means. Also set the encoding of
272 stdin and stdout if these are terminals. */
273
274 codeset = get_codeset();
275 if (codeset) {
276 if (!Py_FileSystemDefaultEncoding)
277 Py_FileSystemDefaultEncoding = codeset;
278 else
279 free(codeset);
280 }
281 #endif
282 265
283 if (install_sigs) 266 if (install_sigs)
284 initsigs(); /* Signal handling stuff, including initintr() */ 267 initsigs(); /* Signal handling stuff, including initintr() */
285 268
286 /* Initialize warnings. */ 269 /* Initialize warnings. */
494 477
495 /* Cleanup Unicode implementation */ 478 /* Cleanup Unicode implementation */
496 _PyUnicode_Fini(); 479 _PyUnicode_Fini();
497 480
498 /* reset file system default encoding */ 481 /* reset file system default encoding */
499 if (!Py_HasFileSystemDefaultEncoding) { 482 if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
500 free((char*)Py_FileSystemDefaultEncoding); 483 free((char*)Py_FileSystemDefaultEncoding);
501 Py_FileSystemDefaultEncoding = NULL; 484 Py_FileSystemDefaultEncoding = NULL;
502 } 485 }
503 486
504 /* XXX Still allocated: 487 /* XXX Still allocated:
702 PyObject *bimod = PyImport_ImportModule("builtins"); 685 PyObject *bimod = PyImport_ImportModule("builtins");
703 if (bimod == NULL || 686 if (bimod == NULL ||
704 PyDict_SetItemString(d, "__builtins__", bimod) != 0) 687 PyDict_SetItemString(d, "__builtins__", bimod) != 0)
705 Py_FatalError("can't add __builtins__ to __main__"); 688 Py_FatalError("can't add __builtins__ to __main__");
706 Py_DECREF(bimod); 689 Py_DECREF(bimod);
690 }
691 }
692
693 static void
694 initfsencoding(void)
695 {
696 PyObject *codec;
697 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
698 char *codeset;
699
700 /* On Unix, set the file system encoding according to the
701 user's preference, if the CODESET names a well-known
702 Python codec, and Py_FileSystemDefaultEncoding isn't
703 initialized by other means. Also set the encoding of
704 stdin and stdout if these are terminals. */
705 codeset = get_codeset();
706 if (codeset != NULL) {
707 Py_FileSystemDefaultEncoding = codeset;
708 Py_HasFileSystemDefaultEncoding = 0;
709 return;
710 }
711
712 PyErr_Clear();
713 fprintf(stderr,
714 "Unable to get the locale encoding: "
715 "fallback to utf-8\n");
716 Py_FileSystemDefaultEncoding = "utf-8";
717 Py_HasFileSystemDefaultEncoding = 1;
718 #endif
719
720 /* the encoding is mbcs, utf-8 or ascii */
721 codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding);
722 if (!codec) {
723 /* Such error can only occurs in critical situations: no more
724 * memory, import a module of the standard library failed,
725 * etc. */
726 Py_FatalError("Py_Initialize: unable to load the file system codec");
727 } else {
728 Py_DECREF(codec);
707 } 729 }
708 } 730 }
709 731
710 /* Import the site module (not into __main__ though) */ 732 /* Import the site module (not into __main__ though) */
711 733