Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Make terminal escape character configurable using environment #425

Closed
wants to merge 8 commits into from

2 participants

@rinne

variable MOSH_ESCAPE_KEY. Defaults to current Ctrl-^ which is
somewhat problematic for many non-US keyboards.

Signed-off-by: Timo J. Rinne tri@iki.fi

@rinne rinne Make terminal escape character configurable using environment
variable MOSH_ESCAPE_KEY. Defaults to current Ctrl-^ which is
somewhat problematic for many non-US keyboards.

Signed-off-by: Timo J. Rinne <tri@iki.fi>
5def55a
@rinne

This one creates nasty conflict if merged with agent forwarding stuff. I can commit the merge patch also to for-keith branch, if Keith asks me to :).

@keithw

Can you please give tp and te a more descriptive name?

I did. Committed to this same branch.

@keithw

Do we really need the user to be able to set the escape sequence to be the letter "p" by itself or something? What if we just require it to be a control character (< 32)? Seems like that could simplify things.

Well, ssh default is tilde ~ which is ascii 126. I don't really see use case to use alphabets but I can see use case for ~ (that's what I use).

@keithw
Owner

This looks great. Let's do this one first because the agent-forwarding and OOB is going to take a while to review and merge. I left some comments -- can we just require the escape_key to be a control character? Seems like that would simplify this a lot. Otherwise lgtm.

rinne added some commits
@rinne rinne Removed warning. f2032cf
@rinne rinne Variable names.
Signed-off-by: Timo J. Rinne <tri@iki.fi>
b1c5442
@rinne rinne If escape key is a printable character, require it to be immediately
after newline.  Also don't allow setting escape key to Ctrl-C, Ctrl-D,
Newline, or Carriage Return.

Signed-off-by: Timo J. Rinne <tri@iki.fi>
be94e6e
@rinne rinne Removed compilation warning generating always true comparison.
Signed-off-by: Timo J. Rinne <tri@iki.fi>
b1eb37f
@rinne rinne Elaborated the warning removal and made it still explicitly
check that the escape key character is less than 128.

Signed-off-by: Timo J. Rinne <tri@iki.fi>
e4d615d
@rinne rinne Invalid escape key defaults to Ctrl-^ but empty escape
key causes there being no escape key at all.

Signed-off-by: Timo J. Rinne <tri@iki.fi>
dce460f
@rinne rinne Set escape pass key correctly in default case.
Signed-off-by: Timo J. Rinne <tri@iki.fi>
daa6a2f
@keithw keithw closed this pull request from a commit
@rinne rinne mosh-client: Make terminal escape character configurable
Uses environment variable MOSH_ESCAPE_KEY. Defaults to current Ctrl-^
which is somewhat problematic for many non-US keyboards.

Signed-off-by: Timo J. Rinne <tri@iki.fi>

Closes #425. Closes #215.
f960a8b
@keithw keithw closed this in f960a8b
@antrorsum antrorsum referenced this pull request from a commit in antrorsum/mosh
@antrorsum antrorsum Squashed commit of the following:
commit c6bf3a2
Author: Barosl LEE <vcs@barosl.com>
Date:   Wed May 29 12:54:29 2013 +0900

    Implement bracketed paste mode

    Allow bracketed paste mode-setting control sequences to be passed to the
    outer terminal.

    Signed-off-by: Barosl LEE <vcs@barosl.com>

    Closes #430

commit 06561d3
Author: Daniel "Tracerneo" Ziółkowski <ziolkoneo@gmail.com>
Date:   Fri Jun 28 04:28:32 2013 +0200

    Add support for ECMA-48 escape sequence for italic

    Closes #443

commit d871161
Author: Andrew Chin <achin@eminence32.net>
Date:   Tue May 14 19:58:58 2013 -0400

    Set MACOSX_DEPLOYMENT_TARGET so that older macs can run the mosh binaries

    Closes #424

commit c3e31f1
Author: Keith Winstein <keithw@mit.edu>
Date:   Wed Jun 5 19:19:05 2013 +0200

    Get rid of obsolete DM-Upload-Allowed field

commit f960a8b
Author: Timo J. Rinne <tri@iki.fi>
Date:   Thu May 16 18:09:15 2013 +0000

    mosh-client: Make terminal escape character configurable

    Uses environment variable MOSH_ESCAPE_KEY. Defaults to current Ctrl-^
    which is somewhat problematic for many non-US keyboards.

    Signed-off-by: Timo J. Rinne <tri@iki.fi>

    Closes #425. Closes #215.

commit 4792992
Author: Keith Winstein <keithw@mit.edu>
Date:   Sun Apr 28 15:33:36 2013 -0400

    Rename --bind-ip to --bind-server, add =ANY option, add error checking.

    Closes #415.

commit fc70612
Author: Philipp Haselwarter <philipp@haselwarter.org>
Date:   Tue Apr 16 18:37:40 2013 +0200

    mosh perl wrapper: New option --bind-ip={ssh|IP}

    Allow overriding the switch passed to mosh-server from -s to -i IP.

    Signed-off-by: Philipp Haselwarter <philipp@haselwarter.org>

commit 9314ea1
Author: Jérémie Courrèges-Anglas <jca@wxcvbn.org>
Date:   Tue Apr 16 11:11:45 2013 +0200

    use betoh64 if be64toh not found

    Instead of looking for htobe64 which is be available both when
    be64toh or betoh64 are, check for the latter functions.  If we
    find betoh64 but not be64toh, use compat #defines.  If both
    can't be found, search for OSX' OSSwapHostToBigInt64.
    Also include sys/types.h in byteorder.h (which is necessary for
    byteorder functions on OpenBSD), and incidentally fixes build
    of networkfragment.cc.

    Fixes build on OpenBSD

    Signed-off-by: Jérémie Courrèges-Anglas <jca@wxcvbn.org>

commit 24b078a
Author: Jérémie Courrèges-Anglas <jca@wxcvbn.org>
Date:   Tue Apr 16 11:09:42 2013 +0200

    workaround for systems not providing pselect

    using a mix of good old select and sigprocmask

    Signed-off-by: Jérémie Courrèges-Anglas <jca@wxcvbn.org>

commit fbd2d18
Author: Andrew Chin <achin@eminence32.net>
Date:   Sat Mar 30 23:26:52 2013 -0400

    In the OSX build script, link with system libs.

    Previously, mosh was linking with macports-provided libs in
    /opt/local/lib, which was not portable to users without macports

    Closes #411

commit 8ff636d
Author: Anders Kaseorg <andersk@mit.edu>
Date:   Tue Apr 9 18:04:43 2013 -0400

    Work around automake bug that dropped portability warnings

    There’s a bug in automake ≥ 1.10, < 1.12 where ‘-Wall foreign’
    incorrectly turns off warnings about portability issues.  To get
    consistent results across automake versions, use ‘foreign -Wall’
    instead.

    http://debbugs.gnu.org/cgi-bin/bugreport.cgi?bug=7669

    Signed-off-by: Anders Kaseorg <andersk@mit.edu>

    Closes #413

commit fb39fe2
Author: Anton Lundin <glance@acc.umu.se>
Date:   Tue Jan 22 20:29:01 2013 +0100

    Simplify pipe management

    We don't need to write perl like C.

commit 1b9915f
Author: Keith Winstein <keithw@mit.edu>
Date:   Wed Mar 27 18:34:21 2013 -0400

    Bump version to 1.2.4a

commit 9669178
Author: Keith Winstein <keithw@mit.edu>
Date:   Wed Mar 27 15:21:20 2013 -0400

    Eliminate ocb.cc test program (closes #408)

    This test doesn't return an error on failure and also was triggering a
    stack protector warning on some platforms. We have an end-to-end test of
    OCB in src/tests/ocb-aes.cc that seems to work well.

commit 4a37359
Author: Alexander Chernyakhovsky <achernya@mit.edu>
Date:   Wed Mar 27 14:49:58 2013 -0400

    Update mosh.spec for mosh 1.2.4

commit 172b1e5
Author: Alexander Chernyakhovsky <achernya@mit.edu>
Date:   Wed Mar 27 02:15:25 2013 -0400

    Cast time_elapsed to int before calling human_readable_duration

    When attempting to build againt EPEL 5, it was noticed that
    human_readable_duration expects an int, but time_elapsed is an
    integer.  Explicitly static_cast<int>( time_elapsed ) to appease older
    compilers.

commit 688bf21
Author: Keith Winstein <keithw@mit.edu>
Date:   Wed Mar 27 00:28:47 2013 -0400

    Bump version to 1.2.4

commit 61c6ee6
Author: Keith Winstein <keithw@mit.edu>
Date:   Wed Mar 27 00:26:59 2013 -0400

    Send SIGSTOP to whole process group on suspend (closes #401)
c47a8c3
@rinne rinne deleted the rinne:terminal-esc-for-keithw branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 16, 2013
  1. @rinne

    Make terminal escape character configurable using environment

    rinne authored
    variable MOSH_ESCAPE_KEY. Defaults to current Ctrl-^ which is
    somewhat problematic for many non-US keyboards.
    
    Signed-off-by: Timo J. Rinne <tri@iki.fi>
Commits on May 17, 2013
  1. @rinne

    Removed warning.

    rinne authored
  2. @rinne

    Variable names.

    rinne authored
    Signed-off-by: Timo J. Rinne <tri@iki.fi>
  3. @rinne

    If escape key is a printable character, require it to be immediately

    rinne authored
    after newline.  Also don't allow setting escape key to Ctrl-C, Ctrl-D,
    Newline, or Carriage Return.
    
    Signed-off-by: Timo J. Rinne <tri@iki.fi>
  4. @rinne

    Removed compilation warning generating always true comparison.

    rinne authored
    Signed-off-by: Timo J. Rinne <tri@iki.fi>
  5. @rinne

    Elaborated the warning removal and made it still explicitly

    rinne authored
    check that the escape key character is less than 128.
    
    Signed-off-by: Timo J. Rinne <tri@iki.fi>
  6. @rinne

    Invalid escape key defaults to Ctrl-^ but empty escape

    rinne authored
    key causes there being no escape key at all.
    
    Signed-off-by: Timo J. Rinne <tri@iki.fi>
  7. @rinne

    Set escape pass key correctly in default case.

    rinne authored
    Signed-off-by: Timo J. Rinne <tri@iki.fi>
This page is out of date. Refresh to see the latest.
Showing with 89 additions and 12 deletions.
  1. +79 −11 src/frontend/stmclient.cc
  2. +10 −1 src/frontend/stmclient.h
View
90 src/frontend/stmclient.cc
@@ -121,6 +121,72 @@ void STMClient::init( void )
overlays.set_title_prefix( wstring( L"[mosh] " ) );
}
+ /* Set terminal escape key. */
+ const char *escape_key_env;
+ if ( (escape_key_env = getenv( "MOSH_ESCAPE_KEY" )) != NULL ) {
+ if ( strlen( escape_key_env ) == 1 ) {
+ escape_key = (int)escape_key_env[0];
+ if ( (escape_key > 0) || (escape_key < 128) ) {
+ if ( escape_key < 32 ) {
+ /* If escape is ctrl-something, pass it with repeating the key without ctrl. */
+ escape_pass_key = escape_key + (int)'@';
+ } else {
+ /* If escape is something else, pass it with repeating the key itself. */
+ escape_pass_key = escape_key;
+ }
+ if ( escape_pass_key >= 'A' && escape_pass_key <= 'Z' ) {
+ /* If escape pass is an upper case character, define optional version
+ as lower case of the same. */
+ escape_pass_key2 = escape_pass_key + (int)'a' - (int)'A';
+ } else {
+ escape_pass_key2 = escape_pass_key;
+ }
+ } else {
+ escape_key = 0x1E;
+ escape_pass_key = '^';
+ escape_pass_key2 = '^';
+ }
+ } else if ( strlen( escape_key_env ) == 0 ) {
+ escape_key = -1;
+ } else {
+ escape_key = 0x1E;
+ escape_pass_key = '^';
+ escape_pass_key2 = '^';
+ }
+ } else {
+ escape_key = 0x1E;
+ escape_pass_key = '^';
+ escape_pass_key2 = '^';
+ }
+
+ /* There are so many better ways to shoot oneself into leg than
+ setting escape key to Ctrl-C, Ctrl-D, NewLine, Ctrl-L or CarriageReturn
+ that we just won't allow that. */
+ if ( escape_key == 0x03 || escape_key == 0x04 || escape_key == 0x0A || escape_key == 0x0C || escape_key == 0x0D ) {
+ escape_key = 0x1E;
+ escape_pass_key = '^';
+ escape_pass_key2 = '^';
+ }
+
+ /* Adjust escape help differently if escape is a control character. */
+ if ( escape_key > 0 ) {
+ char escape_pass_name_buf[16];
+ char escape_key_name_buf[16];
+ sprintf(escape_pass_name_buf, "\"%c\"", escape_pass_key);
+ if (escape_key < 32) {
+ sprintf(escape_key_name_buf, "Ctrl-%c", escape_pass_key);
+ escape_requires_lf = false;
+ } else {
+ sprintf(escape_key_name_buf, "\"%c\"", escape_key);
+ escape_requires_lf = true;
+ }
+ string tmp;
+ tmp = string( escape_pass_name_buf );
+ wstring escape_pass_name = std::wstring(tmp.begin(), tmp.end());
+ tmp = string( escape_key_name_buf );
+ wstring escape_key_name = std::wstring(tmp.begin(), tmp.end());
+ escape_key_help = L"Commands: Ctrl-Z suspends, \".\" quits, " + escape_pass_name + L" gives literal " + escape_key_name;
+ }
wchar_t tmp[ 128 ];
swprintf( tmp, 128, L"Nothing received from server on UDP port %d.", port );
connecting_notification = wstring( tmp );
@@ -255,8 +321,6 @@ bool STMClient::process_user_input( int fd )
overlays.get_prediction_engine().new_user_byte( the_byte, *local_framebuffer );
- const static wstring help_message( L"Commands: Ctrl-Z suspends, \".\" quits, \"^\" gives literal Ctrl-^" );
-
if ( quit_sequence_started ) {
if ( the_byte == '.' ) { /* Quit sequence is Ctrl-^ . */
if ( network->has_remote_addr() && (!network->shutdown_in_progress()) ) {
@@ -266,7 +330,7 @@ bool STMClient::process_user_input( int fd )
} else {
return false;
}
- } else if ( the_byte == 0x1a ) { /* Suspend sequence is Ctrl-^ Ctrl-Z */
+ } else if ( the_byte == 0x1a ) { /* Suspend sequence is escape_key Ctrl-Z */
/* Restore terminal and terminal-driver state */
swrite( STDOUT_FILENO, display.close().c_str() );
@@ -283,30 +347,34 @@ bool STMClient::process_user_input( int fd )
kill( 0, SIGSTOP );
resume();
- } else if ( the_byte == '^' ) {
- /* Emulation sequence to type Ctrl-^ is Ctrl-^ ^ */
- network->get_current_state().push_back( Parser::UserByte( 0x1E ) );
+ } else if ( (the_byte == escape_pass_key) || (the_byte == escape_pass_key2) ) {
+ /* Emulation sequence to type escape_key is escape_key +
+ escape_pass_key (that is escape key without Ctrl) */
+ network->get_current_state().push_back( Parser::UserByte( escape_key ) );
} else {
- /* Ctrl-^ followed by anything other than . and ^ gets sent literally */
- network->get_current_state().push_back( Parser::UserByte( 0x1E ) );
+ /* Escape key followed by anything other than . and ^ gets sent literally */
+ network->get_current_state().push_back( Parser::UserByte( escape_key ) );
network->get_current_state().push_back( Parser::UserByte( the_byte ) );
}
quit_sequence_started = false;
- if ( overlays.get_notification_engine().get_notification_string() == help_message ) {
+ if ( overlays.get_notification_engine().get_notification_string() == escape_key_help ) {
overlays.get_notification_engine().set_notification_string( L"" );
}
continue;
}
- quit_sequence_started = (the_byte == 0x1E);
+ quit_sequence_started = (escape_key > 0) && (the_byte == escape_key) && (lf_entered || (! escape_requires_lf));
if ( quit_sequence_started ) {
- overlays.get_notification_engine().set_notification_string( help_message, true, false );
+ lf_entered = false;
+ overlays.get_notification_engine().set_notification_string( escape_key_help, true, false );
continue;
}
+ lf_entered = ( (the_byte == 0x0A) || (the_byte == 0x0D) ); /* LineFeed, Ctrl-J, '\n' or CarriageReturn, Ctrl-M, '\r' */
+
if ( the_byte == 0x0C ) { /* Ctrl-L */
repaint_requested = true;
}
View
11 src/frontend/stmclient.h
@@ -48,6 +48,12 @@ class STMClient {
int port;
std::string key;
+ int escape_key;
+ int escape_pass_key;
+ int escape_pass_key2;
+ bool escape_requires_lf;
+ std::wstring escape_key_help;
+
struct termios saved_termios, raw_termios;
struct winsize window_size;
@@ -58,7 +64,7 @@ class STMClient {
Terminal::Display display;
std::wstring connecting_notification;
- bool repaint_requested, quit_sequence_started;
+ bool repaint_requested, lf_entered, quit_sequence_started;
bool clean_shutdown;
void main_init( void );
@@ -79,6 +85,8 @@ class STMClient {
public:
STMClient( const char *s_ip, int s_port, const char *s_key, const char *predict_mode )
: ip( s_ip ), port( s_port ), key( s_key ),
+ escape_key( 0x1E ), escape_pass_key( '^' ), escape_pass_key2( '^' ),
+ escape_requires_lf( false ), escape_key_help( L"?" ),
saved_termios(), raw_termios(),
window_size(),
local_framebuffer( NULL ),
@@ -88,6 +96,7 @@ class STMClient {
display( true ), /* use TERM environment var to initialize display */
connecting_notification(),
repaint_requested( false ),
+ lf_entered( false ),
quit_sequence_started( false ),
clean_shutdown( false )
{
Something went wrong with that request. Please try again.