Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL
-DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall
uname output: Linux violino 2.6.34-5-generic #14~lucid1-Ubuntu SMP Thu Jun 3
14:51:20 UTC 2010 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 4.1
Patch Level: 5
Release Status: release
Description:
bash / readline currently forces terminals into character-at-a-time
operation. This is unfriendly for users on slow networks or networks with high
per-byte fees. Since 1989 there has been an approach called LINEMODE for
clients to interact with remote servers while still handling all line editing
and character processing locally. (See RFC1116 and RFC1184.) But this feature
is rendered useless when such ubiquitous software as bash and readline force
character-at-a-time processing.
Repeat-By:
Try to connect to your favorite server using a cellphone network
connection. Aside from the terrible input lag, if you do this while roaming
you'll run up a nasty bill at the same time. If you happen to have an up to
date Telnet client and a BSD server, you'll notice that input responsiveness
is a lot better, as long as you use a "dumb" shell. You can't repeat this
experiment on current Linux systems because the Linux kernel never adopted the
tty driver feature needed to support it.
Fix:
The attached patch will make readline check for the EXTPROC tty mode and
bypass most of its I/O processing features if EXTPROC is detected. (Input
prompt handling must still be done.)
Patches for the Linux kernel to support the EXTPROC features are
available here
http://lkml.org/lkml/2010/6/11/403
Patches to get Telnet working with the Linux support are available here
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=585527
Preliminary patches to get OpenSSH working with linemode are available here
http://marc.info/?l=openssh-unix-dev&m=127655706101347&w=2
Note that these OpenSSH patches were a very rough cut. I'll be posting an
updated patch shortly that also supports command history. In the meantime I'm
working on further readline patches to support command completion between the
client and the server. (And no one will be more surprised than me if that
actually works...)
This combination of patches is giving me pretty reasonable terminal behavior
now, but obviously a lot of it is rough. Feedback appreciated.
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
diff -wur bash-4.1/bash/lib/readline/display.c
bash-4.1.N/bash/lib/readline/display.c
--- bash-4.1/bash/lib/readline/display.c 2009-09-26 11:37:33.000000000
-0700
+++ bash-4.1.N/bash/lib/readline/display.c 2010-06-14 22:54:30.000000000
-0700
@@ -65,6 +65,8 @@
static void insert_some_chars PARAMS((char *, int, int));
static void cr PARAMS((void));
+int _rl_extproc;
+
/* State of visible and invisible lines. */
struct line_state
{
@@ -728,6 +730,8 @@
It maintains an array of line breaks for display (inv_lbreaks).
This handles expanding tabs for display and displaying meta characters. */
lb_linenum = 0;
+ if (_rl_extproc) goto do_ext;
+
#if defined (HANDLE_MULTIBYTE)
in = 0;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@@ -902,6 +906,7 @@
#endif
}
+do_ext:
line[out] = '\0';
if (cpos_buffer_position < 0)
{
diff -wur bash-4.1/bash/lib/readline/rlprivate.h
bash-4.1.N/bash/lib/readline/rlprivate.h
--- bash-4.1/bash/lib/readline/rlprivate.h 2009-08-31 05:46:04.000000000
-0700
+++ bash-4.1.N/bash/lib/readline/rlprivate.h 2010-06-14 22:20:03.000000000
-0700
@@ -396,6 +396,7 @@
extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern int _rl_want_redisplay;
+extern int _rl_extproc;
/* isearch.c */
extern char *_rl_isearch_terminators;
diff -wur bash-4.1/bash/lib/readline/rltty.c
bash-4.1.N/bash/lib/readline/rltty.c
--- bash-4.1/bash/lib/readline/rltty.c 2009-11-19 06:42:02.000000000 -0800
+++ bash-4.1.N/bash/lib/readline/rltty.c 2010-06-14 22:18:32.000000000
-0700
@@ -521,6 +521,12 @@
_rl_echoctl = (oldtio.c_lflag & ECHOCTL);
#endif
+ if (oldtio.c_lflag & EXTPROC) {
+ tiop->c_cc[VEOL] = 9; /* TAB */
+ _rl_extproc = 1;
+ return;
+ }
+
tiop->c_lflag &= ~(ICANON | ECHO);
if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
diff -wur bash-4.1/bash/lib/readline/text.c bash-4.1.N/bash/lib/readline/text.c
--- bash-4.1/bash/lib/readline/text.c 2009-09-07 10:40:57.000000000 -0700
+++ bash-4.1.N/bash/lib/readline/text.c 2010-06-14 23:22:02.000000000 -0700
@@ -971,7 +971,7 @@
if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
return 0;
- if (_rl_echoing_p)
+ if (_rl_echoing_p && !_rl_extproc)
_rl_update_final ();
return 0;
}