@@ -134,18 +134,13 @@ add_flag(int flag, const char *envs)
134134 return flag ;
135135}
136136
137- #if defined(HAVE_LANGINFO_H ) && defined(CODESET )
138137static char *
139- get_codeset ( void )
138+ get_codec_name ( const char * encoding )
140139{
141- char * codeset , * name_str ;
140+ char * name_utf8 , * name_str ;
142141 PyObject * codec , * name = NULL ;
143142
144- codeset = nl_langinfo (CODESET );
145- if (!codeset || codeset [0 ] == '\0' )
146- return NULL ;
147-
148- codec = _PyCodec_Lookup (codeset );
143+ codec = _PyCodec_Lookup (encoding );
149144 if (!codec )
150145 goto error ;
151146
@@ -154,18 +149,34 @@ get_codeset(void)
154149 if (!name )
155150 goto error ;
156151
157- name_str = _PyUnicode_AsString (name );
152+ name_utf8 = _PyUnicode_AsString (name );
158153 if (name == NULL )
159154 goto error ;
160- codeset = strdup (name_str );
155+ name_str = strdup (name_utf8 );
161156 Py_DECREF (name );
162- return codeset ;
157+ if (name_str == NULL ) {
158+ PyErr_NoMemory ();
159+ return NULL ;
160+ }
161+ return name_str ;
163162
164163error :
165164 Py_XDECREF (codec );
166165 Py_XDECREF (name );
167166 return NULL ;
168167}
168+
169+ #if defined(HAVE_LANGINFO_H ) && defined(CODESET )
170+ static char *
171+ get_codeset (void )
172+ {
173+ char * codeset = nl_langinfo (CODESET );
174+ if (!codeset || codeset [0 ] == '\0' ) {
175+ PyErr_SetString (PyExc_ValueError , "CODESET is not set or empty" );
176+ return NULL ;
177+ }
178+ return get_codec_name (codeset );
179+ }
169180#endif
170181
171182void
@@ -706,25 +717,35 @@ initfsencoding(void)
706717{
707718 PyObject * codec ;
708719#if defined(HAVE_LANGINFO_H ) && defined(CODESET )
709- char * codeset ;
720+ char * codeset = NULL ;
710721
711722 if (Py_FileSystemDefaultEncoding == NULL ) {
712- /* On Unix, set the file system encoding according to the
713- user's preference, if the CODESET names a well-known
714- Python codec, and Py_FileSystemDefaultEncoding isn't
715- initialized by other means. Also set the encoding of
716- stdin and stdout if these are terminals. */
717- codeset = get_codeset ();
723+ const char * env_encoding = Py_GETENV ("PYTHONFSENCODING" );
724+ if (env_encoding != NULL ) {
725+ codeset = get_codec_name (env_encoding );
726+ if (!codeset ) {
727+ fprintf (stderr , "PYTHONFSENCODING is not a valid encoding:\n" );
728+ PyErr_Print ();
729+ }
730+ }
731+ if (!codeset ) {
732+ /* On Unix, set the file system encoding according to the
733+ user's preference, if the CODESET names a well-known
734+ Python codec, and Py_FileSystemDefaultEncoding isn't
735+ initialized by other means. Also set the encoding of
736+ stdin and stdout if these are terminals. */
737+ codeset = get_codeset ();
738+ }
718739 if (codeset != NULL ) {
719740 Py_FileSystemDefaultEncoding = codeset ;
720741 Py_HasFileSystemDefaultEncoding = 0 ;
721742 return ;
743+ } else {
744+ fprintf (stderr , "Unable to get the locale encoding:\n" );
745+ PyErr_Print ();
722746 }
723747
724- PyErr_Clear ();
725- fprintf (stderr ,
726- "Unable to get the locale encoding: "
727- "fallback to utf-8\n" );
748+ fprintf (stderr , "Unable to get the filesystem encoding: fallback to utf-8\n" );
728749 Py_FileSystemDefaultEncoding = "utf-8" ;
729750 Py_HasFileSystemDefaultEncoding = 1 ;
730751 }
0 commit comments