summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Winstein <keithw@mit.edu>2012-04-19 02:35:14 -0400
committerKeith Winstein <keithw@mit.edu>2012-04-19 02:35:14 -0400
commitb9a8b8c0091571723f085829d95fa8075c0c3ace (patch)
treeed06720ff0c7585c46f092399fb189f997c6b565
parent58589787eae15730b39f5ca91bec0e9ce68e4dbd (diff)
More helpful messages when locale not found or wrong (closes #209)
-rw-r--r--src/frontend/mosh-server.cc10
-rw-r--r--src/frontend/stmclient.cc5
-rw-r--r--src/util/locale_utils.cc42
-rw-r--r--src/util/locale_utils.h12
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 );