Convey locale-related environment variables as backup, and nicer error.

Fixes #74.
This commit is contained in:
Keith Winstein
2012-04-14 16:39:07 -04:00
parent 597756b846
commit 8f60f7ab05
10 changed files with 114 additions and 15 deletions
+1 -1
View File
@@ -61,7 +61,7 @@ int main( void )
/* Adopt native locale */
set_native_locale();
assert_utf8_locale();
assert( is_utf8_locale() );
for ( int i = 0; i < ITERATIONS; i++ ) {
/* type a character */
+1 -1
View File
@@ -57,7 +57,7 @@ int main( int argc __attribute__((unused)),
struct termios saved_termios, raw_termios, child_termios;
set_native_locale();
assert_utf8_locale();
assert( is_utf8_locale() );
if ( tcgetattr( STDIN_FILENO, &saved_termios ) < 0 ) {
perror( "tcgetattr" );
+1 -1
View File
@@ -62,7 +62,7 @@ int main( void )
struct termios saved_termios, raw_termios, child_termios;
set_native_locale();
assert_utf8_locale();
assert( is_utf8_locale() );
if ( tcgetattr( STDIN_FILENO, &saved_termios ) < 0 ) {
perror( "tcgetattr" );
+28 -3
View File
@@ -72,7 +72,7 @@ using namespace std;
void print_usage( const char *argv0 )
{
fprintf( stderr, "Usage: %s new [-s] [-v] [-i LOCALADDR] [-p PORT] [-c COLORS] [-- COMMAND...]\n", argv0 );
fprintf( stderr, "Usage: %s new [-s] [-v] [-i LOCALADDR] [-p PORT] [-c COLORS] [-l NAME=VALUE] [-- COMMAND...]\n", argv0 );
}
/* Simple spinloop */
@@ -113,6 +113,7 @@ int main( int argc, char *argv[] )
int colors = 0;
bool verbose = false; /* don't close stdin/stdout/stderr */
/* Will cause mosh-server not to correctly detach on old versions of sshd. */
list<string> locale_vars;
/* strip off command */
for ( int i = 0; i < argc; i++ ) {
@@ -130,7 +131,7 @@ int main( int argc, char *argv[] )
&& (strcmp( argv[ 1 ], "new" ) == 0) ) {
/* new option syntax */
int opt;
while ( (opt = getopt( argc - 1, argv + 1, "i:p:c:sv" )) != -1 ) {
while ( (opt = getopt( argc - 1, argv + 1, "i:p:c:svl:" )) != -1 ) {
switch ( opt ) {
case 'i':
desired_ip = optarg;
@@ -148,6 +149,9 @@ int main( int argc, char *argv[] )
case 'v':
verbose = true;
break;
case 'l':
locale_vars.push_back( string( optarg ) );
break;
default:
print_usage( argv[ 0 ] );
/* don't die on unknown options */
@@ -203,7 +207,28 @@ int main( int argc, char *argv[] )
/* Adopt implementation locale */
set_native_locale();
assert_utf8_locale();
if ( !is_utf8_locale() ) {
/* apply locale-related environment variables from client */
clear_locale_variables();
for ( list<string>::const_iterator i = locale_vars.begin();
i != locale_vars.end();
i++ ) {
char *env_string = strdup( i->c_str() );
assert( env_string );
if ( 0 != putenv( env_string ) ) {
perror( "putenv" );
}
}
/* check again */
set_native_locale();
if ( !is_utf8_locale() ) {
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() );
int unused __attribute((unused)) = system( "locale" );
exit( 1 );
}
}
try {
return run_server( desired_ip, desired_port, command, colors, verbose );
+6 -1
View File
@@ -49,7 +49,12 @@
void STMClient::init( void )
{
assert_utf8_locale();
if ( !is_utf8_locale() ) {
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() );
int unused __attribute((unused)) = system( "locale" );
exit( 1 );
}
/* Verify terminal configuration */
if ( tcgetattr( STDIN_FILENO, &saved_termios ) < 0 ) {
+38 -7
View File
@@ -29,19 +29,50 @@
#include "locale_utils.h"
void assert_utf8_locale( void ) {
/* Verify locale calls for UTF-8 */
if ( strcmp( nl_langinfo( CODESET ), "UTF-8" ) != 0 &&
strcmp( nl_langinfo( CODESET ), "utf-8" ) != 0 ) {
fprintf( stderr, "mosh requires a UTF-8 locale.\n" );
exit( 1 );
const char *locale_charset( void )
{
static const char ASCII_name[] = "US-ASCII (ANSI_X3.4-1968)";
/* Produce more pleasant name of US-ASCII */
const char *ret = nl_langinfo( CODESET );
if ( strcmp( ret, "ANSI_X3.4-1968" ) == 0 ) {
ret = ASCII_name;
}
return ret;
}
bool is_utf8_locale( void ) {
/* Verify locale calls for UTF-8 */
if ( strcmp( locale_charset(), "UTF-8" ) != 0 &&
strcmp( locale_charset(), "utf-8" ) != 0 ) {
return 0;
}
return 1;
}
void set_native_locale( void ) {
/* Adopt native locale */
if ( NULL == setlocale( LC_ALL, "" ) ) {
perror( "setlocale" );
exit( 1 );
}
}
void clear_locale_variables( void ) {
unsetenv( "LANG" );
unsetenv( "LANGUAGE" );
unsetenv( "LC_CTYPE" );
unsetenv( "LC_NUMERIC" );
unsetenv( "LC_TIME" );
unsetenv( "LC_COLLATE" );
unsetenv( "LC_MONETARY" );
unsetenv( "LC_MESSAGES" );
unsetenv( "LC_PAPER" );
unsetenv( "LC_NAME" );
unsetenv( "LC_ADDRESS" );
unsetenv( "LC_TELEPHONE" );
unsetenv( "LC_MEASUREMENT" );
unsetenv( "LC_IDENTIFICATION" );
unsetenv( "LC_ALL" );
}
+3 -1
View File
@@ -19,7 +19,9 @@
#ifndef LOCALE_UTILS_HPP
#define LOCALE_UTILS_HPP
void assert_utf8_locale( void );
const char *locale_charset( void );
bool is_utf8_locale( void );
void set_native_locale( void );
void clear_locale_variables( void );
#endif