top: correct loss of keystrokes paste capability

When top introduced true line input editing, the
ability to paste keystrokes was lost.  This remains
a necessary evil so that top has an opportunity to
translate cursor motion keystrokes into terminfo
escapes during line input.  Motion keys themselves,
of course, can never be pasted.

If pasting ever became more important than input
editing, then native termios support should have been
available via a define called TERMIOS_ONLY.  But a
recent commit, eliminating what was thought to be
obsolete logic, rendered the alternate linein()
function virtually useless.

Similar to top-3.2.8, when native termios input is
functional, these abberations can be experienced:
. cursor motion keys will appear as escapes
. excessive input can cause line wraps
. ^Z during i/p is not be honored until <Enter>
. SIGWINCH during i/p corrupts screen temporarily

In hindsight, it now seems that the ability to paste
keystrokes may indeed outweigh any shortcomings of
native termios support.  This is especially true if
one is preparing to search ('L') for some lengthy
process command line contined in the clipboard.

Thus, this patch fixes the alternate linein() function
and changes TERMIOS_ONLY to TERMIO_PROXY so that top
now defaults to using native termios input.  In turn,
that will restore the paste keystrokes capability.

Reference(s):
commit: 045538e01b

Reported by: sergio <mailbox@sergio.spb.ru>
Bug-Debian:  http://bugs.debian.org/663334

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2012-03-12 12:12:12 -05:00 committed by Craig Small
parent 42380330d7
commit fa21a6ca81
2 changed files with 11 additions and 6 deletions

View File

@ -60,7 +60,7 @@
/* The original and new terminal definitions /* The original and new terminal definitions
(only set when not in 'Batch' mode) */ (only set when not in 'Batch' mode) */
static struct termios Tty_original, // our inherited terminal definition static struct termios Tty_original, // our inherited terminal definition
#ifdef TERMIOS_ONLY #ifndef TERMIO_PROXY
Tty_tweaked, // for interactive 'line' input Tty_tweaked, // for interactive 'line' input
#endif #endif
Tty_raw; // for unsolicited input Tty_raw; // for unsolicited input
@ -824,7 +824,7 @@ static int chin (int ech, char *buf, unsigned cnt) {
int rc = -1; int rc = -1;
fflush(stdout); fflush(stdout);
#ifdef TERMIOS_ONLY #ifndef TERMIO_PROXY
if (ech) { if (ech) {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_tweaked); tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_tweaked);
rc = read(STDIN_FILENO, buf, cnt); rc = read(STDIN_FILENO, buf, cnt);
@ -922,18 +922,21 @@ static int keyin (int init) {
} // end: keyin } // end: keyin
#ifdef TERMIOS_ONLY #ifndef TERMIO_PROXY
/* /*
* Get line oriented interactive input from the user, * Get line oriented interactive input from the user,
* using native tty support */ * using native tty support */
static char *linein (const char *prompt) { static char *linein (const char *prompt) {
static const char ws[] = "\b\f\n\r\t\v\x1b\x9b"; // 0x1b + 0x9b are escape
static char buf[MEDBUFSIZ]; static char buf[MEDBUFSIZ];
char *p;
show_pmt(prompt); show_pmt(prompt);
memset(buf, '\0', sizeof(buf)); memset(buf, '\0', sizeof(buf));
chin(1, buf, sizeof(buf)-1); chin(1, buf, sizeof(buf)-1);
putp(Cap_curs_norm); putp(Cap_curs_norm);
if ((p = strpbrk(buf, ws))) *p = '\0';
// note: we DO produce a vaid 'string' // note: we DO produce a vaid 'string'
return buf; return buf;
} // end: linein } // end: linein
@ -945,7 +948,9 @@ static char *linein (const char *prompt) {
* Unlike native tty input support, this function provides: * Unlike native tty input support, this function provides:
* . true line editing, not just destructive backspace * . true line editing, not just destructive backspace
* . an input limit that's sensitive to current screen dimensions * . an input limit that's sensitive to current screen dimensions
* . immediate signal response without the need to wait for '\n' */ * . immediate signal response without the need to wait for '\n'
* However, the user will loose the ability to paste keystrokes
* when this function is chosen over the smaller alternative above! */
static char *linein (const char *prompt) { static char *linein (const char *prompt) {
// thank goodness memmove allows the two strings to overlap // thank goodness memmove allows the two strings to overlap
#define sqzSTR { memmove(&buf[pos], &buf[pos+1], bufMAX-pos); \ #define sqzSTR { memmove(&buf[pos], &buf[pos+1], bufMAX-pos); \
@ -2517,7 +2522,7 @@ static void whack_terminal (void) {
tmptty.c_iflag &= ~IGNBRK; tmptty.c_iflag &= ~IGNBRK;
if (key_backspace && 1 == strlen(key_backspace)) if (key_backspace && 1 == strlen(key_backspace))
tmptty.c_cc[VERASE] = *key_backspace; tmptty.c_cc[VERASE] = *key_backspace;
#ifdef TERMIOS_ONLY #ifndef TERMIO_PROXY
if (-1 == tcsetattr(STDIN_FILENO, TCSAFLUSH, &tmptty)) if (-1 == tcsetattr(STDIN_FILENO, TCSAFLUSH, &tmptty))
error_exit(fmtmk(N_fmt(FAIL_tty_mod_fmt), strerror(errno))); error_exit(fmtmk(N_fmt(FAIL_tty_mod_fmt), strerror(errno)));
tcgetattr(STDIN_FILENO, &Tty_tweaked); tcgetattr(STDIN_FILENO, &Tty_tweaked);

View File

@ -40,7 +40,7 @@
//#define RCFILE_NOERR /* rcfile errs silently default, vs. fatal */ //#define RCFILE_NOERR /* rcfile errs silently default, vs. fatal */
//#define RMAN_IGNORED /* don't consider auto right margin glitch */ //#define RMAN_IGNORED /* don't consider auto right margin glitch */
//#define STRCMPNOCASE /* use strcasecmp vs. strcmp when sorting */ //#define STRCMPNOCASE /* use strcasecmp vs. strcmp when sorting */
//#define TERMIOS_ONLY /* just limp along with native input only */ //#define TERMIO_PROXY /* true line editing, beyond native input */
//#define TREE_NORESET /* sort keys do NOT force forest view OFF */ //#define TREE_NORESET /* sort keys do NOT force forest view OFF */
//#define TREE_ONEPASS /* for speed, tolerate dangling children */ //#define TREE_ONEPASS /* for speed, tolerate dangling children */
//#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */ //#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */