GNOME Bugzilla – Bug 125278
g_dir_open() returns non-UTF8 error message?
Last modified: 2004-12-22 21:47:04 UTC
Glib::Dir throws an exception Glib::FileError if its opening a non existing dir. But calling setlocale(LC_MESSAGES,""); before makes the program abort: #include <glibmm/fileutils.h> #include <iostream> int main(int argc,char **argv){ setlocale(LC_MESSAGES,""); // Comenting this, the exception is caught try{ Glib::Dir dir("/Hola"); } catch(const Glib::FileError& fe){ std::cerr<<fe.what()<<std::endl; } return 0; }
Sorry for my ignorance, but what is the purpose of calling setlocale(LC_MESSAGES,"")?
It is used for localization. With this call the category LC_MESSAGES (correspondig to localizable natural-language messages) is modified according to the environment variables (LANG, LC_MESSAGES or LC_ALL). I usually start my programs with: setlocale(LC_MESSAGES,""); bindtextdomain(PACKAGE,LOCALEDIR); bind_textdomain_codeset(PACKAGE,"UTF-8"); textdomain(PACKAGE); and after writing the po files, the program shows messages and gui labels translated
I do get the error message when I try this on my Red Hat 9, and it does not segfault for me. What distro are you using? Is there anything else strange about your setup?
It has something to do with the locale configuration. Whith my current locale (LANG=es_ES.UTF-8), it aborts, but when I make unsetenv LANG and then the locale is POSIX, I get the error message. I have tested also that the program runs commenting the try and catch block, i.e, running only with the setlocale line. I have upgraded this morning to gtkmm2-2.2.8-0.fdr.3.rh90 and it's the same weird thing
Yes, this happens for me too, also when I use LANG=de_DE,UTF-8. Could you try it in C, please?
Well, in C I think is something like: #include <glib/gdir.h> #include <locale.h> #include <stdio.h> int main(){ setlocale(LC_MESSAGES,""); GError* gerror=0; GDir *dir=g_dir_open("/Hola",0,&gerror); if(gerror) printf("%s\n",gerror->message); return 0; } Compiling with glib2-2.2.1-1 rpm from RedHat, it works, with output Ha ocurrido un error al abrir el directorio '/Hola':·No existe el fichero o el directorio in my current locale (LANG=es_ES.UTF-8) and Error opening directory '/Hola': No such file or directory with LANG=C I have also checked that putting the line #include <locale.h> in the C++ code makes no difference. This line is necessary in C
The exception is caught also in the case the program aborts. However, the line "std::cerr<<fe.what()<<std::endl;" triggers a new exception that is thrown in locale_from_utf8 (convert.cc:192) after the call to: char *const buf = g_locale_from_utf8( utf8_string.data(), utf8_string.bytes(), 0, &bytes_written, &error); fails. "(gdb) print *error" yields: $2 = {domain = 3, code = 1, message = 0x8050300 "UngÃŒltige Bytefolge in Konvertierungseingabe"} . The utf8_string.data() for "LANG="de_DE.ISO8859-15"" reads: "Fehler beim Ã\226ffnen des Verzeichnisses »/Hola«: No such file or directory" . The modified C test: #include <glib/gdir.h> #include <locale.h> #include <stdio.h> int main() { setlocale(LC_MESSAGES,""); GError* gerror1=0; GDir *dir=g_dir_open("/Hola",0,&gerror1); if(gerror1) { GError* gerror2=0; gsize bytes_written = 0; char *const buf = g_locale_from_utf8( gerror1->message, strlen(gerror1->message), 0, &bytes_written, &gerror2); if(gerror2) printf("%s\n",gerror2->message); printf("%s\n",gerror1->message); } return 0; } reproduces the problems in C. Is there any obvious reason that the call g_locale_from_utf8 doesn't work here? Otherwise this is a glib/gtk bug!
Please _attach_ test cases. Maybe we can have a test case that just shows g_locale_from_utf8() without the glib_dir() stuff, now that we know what the data is. std::exception::what() can throw an exception. So I wonder what's the best way to catch such an exception, given that it's used in exception handlers itself.
IMO, it has to be found out whether it is a bug that g_locale_from_utf8() fails. The string passed into it ("Fehler beim Ã\226ffnen des Verzeichnisses »/Hola«") looks like valid UTF-8 as two letters are occupied for each special character, the first one always being "Â".
Created attachment 21458 [details] test.c
Here (test.c) is the test as an attachment. I have also tried hard-coding the text, and it also fails in g_locale_from_utf8(). That is in test.c, but commented out. I am reassigning this to glib, because those people can probably help us to understand this. Either a) The text is not UTF8. If so, then I ask Should it be UTF8? I see nothing here http://developer.gnome.org/doc/API/2.0/glib/glib-File-Utilities.html#g-dir-open or here http://developer.gnome.org/doc/API/2.0/glib/glib-Error-Reporting.html#GError to say that it should be, but most things are UTF8. or b) The text is UTF8 and g_locale_from_utf8() is buggy.
Here are some facts: 1. If I insert const char *charset; g_get_charset (&charset); g_printf ("%s\n", charset); right after your setlocale() call, I get ANSI_X3.4-1968, therefore it is not surprising that you get an error when you are trying to convert the "Ö" to ASCII. 2. If I comment out the setlocale call completely, I still get ANSI_X3.4-1968, but g_locale_from_utf8 doesn't fail. Not surprising since the English message is pure ASCII... 3. If I change LC_MESSAGES to LC_ALL, I get UTF-8 as charset, and g_locale_from_utf8 doesn't fail. Conclusion: Omitting LC_CTYPE from setlocale() restricts you to ASCII, so one has to expect frequent failures from g_locale_from_utf8(). Save yourself the trouble and use LC_ALL.