More helpful messages when locale not found or wrong (closes #209)

This commit is contained in:
Keith Winstein
2012-04-19 02:35:14 -04:00
parent 58589787ea
commit b9a8b8c009
4 changed files with 65 additions and 4 deletions
+9 -1
View File
@@ -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 );
}
+4 -1
View File
@@ -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 );
}
+40 -2
View File
@@ -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" );
}
}
}
+12
View File
@@ -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 );