Anybody want to fix ash's backspace line wrap?

Rob Landley rob at landley.net
Wed May 13 22:24:42 UTC 2009


Wanna see a fun bug?  Try this:

  echo -n blahblahblahblahblah

Now type off the right edge of your terminal, and then hit backspace to try to 
go back up.

The problem is that ash assumes that its shell prompt always starts at the 
left edge of the screen, then adds the length of the prompt it prints to 
figure out where the cursor is.  If you didn't start at the left edge of the 
screen, this doesn't work.

The reason it needs to keep track of this is that unix terminals suck.  
Specifically, backspace won't automatically back you up to the previous line, 
the only way to do multiline interactive editing is to keep track of your 
current cursor position and compare it to the width of your screen (which you 
also have to know) in order know when to cursor _up_ and jump to the right 
edge of the screen.

However, if your shell prompt didn't start at the left edge of the screen 
(which happens surprisingly often), the resulting line editing is completely 
horked once you go past the right edge of the screen.  (Command history 
becomes a lot less fun to use, too.)

It's easy enough to fix once you know what the problem is and decide to 
address it.  We just haven't yet...

Rob

P.S.  While we're at it:  when the shell is in interactive mode and 
CONFIG_FEATURE_EDITING is enabled but we can't query the current tty size, 
and either $COLUMNS and LINES$ are blank, then what we should probably do 
right before printing each prompt is some variant of:

  echo -e "\e[s\e[999C\e[999B\e[6n\e[u"

That should trigger your ansi-compliant console to send back:

  \e[LINES;COLUMNSR

Where LINES is decimal number of lines, and COLUMNS is the decimal number of 
columns.

So you'd then want to teach your ansi escape sequence parsing logic (the stuff 
currently handling cursor up/down/left/right and so on) to understand 
esc[YY;XXR escapes  and use them to set $LINES and $COLUMNS respectively.

Note you probably only want to send that escape sequence if there _isn't_ 
already input pending.  (Has the escape sequence parsing logic I tweaked in 
the VI code last year been genericized yet?)

The reason to do this is it'll drill through to your xterm even through a 
serial console, and return the width and height of the console even when the 
remote system busybox has NO clue what your console size is because that 
information lives on a separate computer.  The shell could then set LINES and 
COLUMNS based on that for the next command it runs, although it should 
remember that they weren't set when the shell was originally run so it 
shouldn't trust those values, and should probably re-query it every prompt in 
that case because we don't get WINCH signals through a serial console 
either...

Anyway, just a thought. :)

Still Rob.
-- 
Latency is more important than throughput. It's that simple. - Linus Torvalds


More information about the busybox mailing list