Commit a2c17c58 authored by Martin v. Löwis's avatar Martin v. Löwis

Move initialization of sys.std{in,out}.encoding to Py_Initialize.

Verify that the encoding actually exists. Fixes #775985.
Will backport to 2.3.
parent fc9b75fa
...@@ -77,7 +77,7 @@ static PyObject *warnings_module = NULL; ...@@ -77,7 +77,7 @@ static PyObject *warnings_module = NULL;
If the module is returned, it is guaranteed to have been obtained If the module is returned, it is guaranteed to have been obtained
without acquiring the import lock without acquiring the import lock
*/ */
PyObject *PyModule_GetWarningsModule() PyObject *PyModule_GetWarningsModule(void)
{ {
PyObject *typ, *val, *tb; PyObject *typ, *val, *tb;
PyObject *all_modules; PyObject *all_modules;
...@@ -142,6 +142,11 @@ Py_Initialize(void) ...@@ -142,6 +142,11 @@ Py_Initialize(void)
PyThreadState *tstate; PyThreadState *tstate;
PyObject *bimod, *sysmod; PyObject *bimod, *sysmod;
char *p; char *p;
#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
char *codeset;
char *saved_locale;
PyObject *sys_stream, *sys_isatty;
#endif
extern void _Py_ReadyTypes(void); extern void _Py_ReadyTypes(void);
if (initialized) if (initialized)
...@@ -227,21 +232,52 @@ Py_Initialize(void) ...@@ -227,21 +232,52 @@ Py_Initialize(void)
/* On Unix, set the file system encoding according to the /* On Unix, set the file system encoding according to the
user's preference, if the CODESET names a well-known user's preference, if the CODESET names a well-known
Python codec, and Py_FileSystemDefaultEncoding isn't Python codec, and Py_FileSystemDefaultEncoding isn't
initialized by other means. */ initialized by other means. Also set the encoding of
if (!Py_FileSystemDefaultEncoding) { stdin and stdout if these are terminals. */
char *saved_locale = setlocale(LC_CTYPE, NULL);
char *codeset; saved_locale = setlocale(LC_CTYPE, NULL);
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
codeset = nl_langinfo(CODESET); codeset = nl_langinfo(CODESET);
if (*codeset) { if (codeset && *codeset) {
PyObject *enc = PyCodec_Encoder(codeset); PyObject *enc = PyCodec_Encoder(codeset);
if (enc) { if (enc) {
Py_FileSystemDefaultEncoding = strdup(codeset); codeset = strdup(codeset);
Py_DECREF(enc); Py_DECREF(enc);
} else } else {
PyErr_Clear(); codeset = NULL;
PyErr_Clear();
}
} else
codeset = NULL;
setlocale(LC_CTYPE, saved_locale);
if (codeset) {
sys_stream = PySys_GetObject("stdout");
sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
if (!sys_isatty)
PyErr_Clear();
if(sys_isatty && PyObject_IsTrue(sys_isatty)) {
if (!PyFile_SetEncoding(sys_stream, codeset))
Py_FatalError("Cannot set codeset of stdin");
} }
setlocale(LC_CTYPE, saved_locale); Py_XDECREF(sys_stream);
Py_XDECREF(sys_isatty);
sys_stream = PySys_GetObject("stdout");
sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
if (!sys_isatty)
PyErr_Clear();
if(sys_isatty && PyObject_IsTrue(sys_isatty)) {
if (!PyFile_SetEncoding(sys_stream, codeset))
Py_FatalError("Cannot set codeset of stdout");
}
Py_XDECREF(sys_stream);
Py_XDECREF(sys_isatty);
if (!Py_FileSystemDefaultEncoding)
Py_FileSystemDefaultEncoding = codeset;
else
free(codeset);
} }
#endif #endif
} }
......
...@@ -905,9 +905,6 @@ _PySys_Init(void) ...@@ -905,9 +905,6 @@ _PySys_Init(void)
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
char buf[10]; char buf[10];
#endif #endif
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
char *oldloc, *codeset;
#endif
m = Py_InitModule3("sys", sys_methods, sys_doc); m = Py_InitModule3("sys", sys_methods, sys_doc);
sysdict = PyModule_GetDict(m); sysdict = PyModule_GetDict(m);
...@@ -930,21 +927,6 @@ _PySys_Init(void) ...@@ -930,21 +927,6 @@ _PySys_Init(void)
} }
#endif #endif
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
oldloc = setlocale(LC_CTYPE, 0);
setlocale(LC_CTYPE, "");
codeset = nl_langinfo(CODESET);
setlocale(LC_CTYPE, oldloc);
if(codeset && isatty(fileno(stdin))){
if (!PyFile_SetEncoding(sysin, codeset))
return NULL;
}
if(codeset && isatty(fileno(stdout))) {
if (!PyFile_SetEncoding(sysout, codeset))
return NULL;
}
#endif
PyDict_SetItemString(sysdict, "stdin", sysin); PyDict_SetItemString(sysdict, "stdin", sysin);
PyDict_SetItemString(sysdict, "stdout", sysout); PyDict_SetItemString(sysdict, "stdout", sysout);
PyDict_SetItemString(sysdict, "stderr", syserr); PyDict_SetItemString(sysdict, "stderr", syserr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment