diff options
author | Keith Winstein <keithw@mit.edu> | 2012-04-19 02:35:14 -0400 |
---|---|---|
committer | Keith Winstein <keithw@mit.edu> | 2012-04-19 02:35:14 -0400 |
commit | b9a8b8c0091571723f085829d95fa8075c0c3ace (patch) | |
tree | ed06720ff0c7585c46f092399fb189f997c6b565 | |
parent | 58589787eae15730b39f5ca91bec0e9ce68e4dbd (diff) |
More helpful messages when locale not found or wrong (closes #209)
-rw-r--r-- | src/frontend/mosh-server.cc | 10 | ||||
-rw-r--r-- | src/frontend/stmclient.cc | 5 | ||||
-rw-r--r-- | src/util/locale_utils.cc | 42 | ||||
-rw-r--r-- | src/util/locale_utils.h | 12 |
4 files changed, 65 insertions, 4 deletions
diff --git a/src/frontend/mosh-server.cc b/src/frontend/mosh-server.cc index 0697bab..112df7f 100644 --- a/src/frontend/mosh-server.cc +++ b/src/frontend/mosh-server.cc @@ -245,6 +245,10 @@ int main( int argc, char *argv[] ) /* Adopt implementation locale */ set_native_locale(); if ( !is_utf8_locale() ) { + /* save details for diagnostic */ + LocaleVar native_ctype = get_ctype(); + string native_charset( locale_charset() ); + /* apply locale-related environment variables from client */ clear_locale_variables(); for ( list<string>::const_iterator i = locale_vars.begin(); @@ -260,8 +264,12 @@ int main( int argc, char *argv[] ) /* check again */ set_native_locale(); if ( !is_utf8_locale() ) { + LocaleVar client_ctype = get_ctype(); + string client_charset( locale_charset() ); + fprintf( stderr, "mosh-server needs a UTF-8 native locale to run.\n\n" ); - fprintf( stderr, "Unfortunately, the locale environment variables currently specify\nthe character set \"%s\".\n\n", locale_charset() ); + fprintf( stderr, "Unfortunately, the local environment (%s) specifies\nthe character set \"%s\",\n\n", native_ctype.str().c_str(), native_charset.c_str() ); + fprintf( stderr, "The client-supplied environment (%s) specifies\nthe character set \"%s\".\n\n", client_ctype.str().c_str(), client_charset.c_str() ); int unused __attribute((unused)) = system( "locale" ); exit( 1 ); } diff --git a/src/frontend/stmclient.cc b/src/frontend/stmclient.cc index e414c8a..02e0463 100644 --- a/src/frontend/stmclient.cc +++ b/src/frontend/stmclient.cc @@ -50,8 +50,11 @@ void STMClient::init( void ) { if ( !is_utf8_locale() ) { + LocaleVar native_ctype = get_ctype(); + string native_charset( locale_charset() ); + fprintf( stderr, "mosh-client needs a UTF-8 native locale to run.\n\n" ); - fprintf( stderr, "Unfortunately, the locale environment variables currently specify\nthe character set \"%s\".\n\n", locale_charset() ); + fprintf( stderr, "Unfortunately, the client's environemnt (%s) specifies\nthe character set \"%s\".\n\n", native_ctype.str().c_str(), native_charset.c_str() ); int unused __attribute((unused)) = system( "locale" ); exit( 1 ); } diff --git a/src/util/locale_utils.cc b/src/util/locale_utils.cc index 90b84c5..6adb6a2 100644 --- a/src/util/locale_utils.cc +++ b/src/util/locale_utils.cc @@ -22,6 +22,8 @@ #include <stdlib.h> #include <stdio.h> #include <locale.h> +#include <errno.h> +#include <string> #if HAVE_LANGINFO_H #include <langinfo.h> @@ -29,9 +31,34 @@ #include "locale_utils.h" +using namespace std; + +const string LocaleVar::str( void ) const +{ + if ( name.empty() ) { + return string( "[no charset variables]" ); + } else { + return name + "=" + value; + } +} + +const LocaleVar get_ctype( void ) +{ + /* Reimplement the search logic, just for diagnostics */ + if ( const char *all = getenv( "LC_ALL" ) ) { + return LocaleVar( "LC_ALL", all ); + } else if ( const char *ctype = getenv( "LC_CTYPE" ) ) { + return LocaleVar( "LC_CTYPE", ctype ); + } else if ( const char *lang = getenv( "LANG" ) ) { + return LocaleVar( "LANG", lang ); + } else { + return LocaleVar( "", "" ); + } +} + const char *locale_charset( void ) { - static const char ASCII_name[] = "US-ASCII (ANSI_X3.4-1968)"; + static const char ASCII_name[] = "US-ASCII"; /* Produce more pleasant name of US-ASCII */ const char *ret = nl_langinfo( CODESET ); @@ -55,7 +82,18 @@ bool is_utf8_locale( void ) { void set_native_locale( void ) { /* Adopt native locale */ if ( NULL == setlocale( LC_ALL, "" ) ) { - perror( "setlocale" ); + int saved_errno = errno; + if ( saved_errno == ENOENT ) { + LocaleVar ctype( get_ctype() ); + fprintf( stderr, "The locale requested by %s isn't available here.\n", ctype.str().c_str() ); + if ( !ctype.name.empty() ) { + fprintf( stderr, "Running `locale-gen %s' may be necessary.\n\n", + ctype.value.c_str() ); + } + } else { + errno = saved_errno; + perror( "setlocale" ); + } } } diff --git a/src/util/locale_utils.h b/src/util/locale_utils.h index 029b901..977b089 100644 --- a/src/util/locale_utils.h +++ b/src/util/locale_utils.h @@ -19,6 +19,18 @@ #ifndef LOCALE_UTILS_HPP #define LOCALE_UTILS_HPP +#include <string> + +class LocaleVar { + public: + const std::string name, value; + LocaleVar( const char *s_name, const char *s_value ) + : name( s_name ), value( s_value ) + {} + const std::string str( void ) const; +}; + +const LocaleVar get_ctype( void ); const char *locale_charset( void ); bool is_utf8_locale( void ); void set_native_locale( void ); |