Anybody want to fix ash's backspace line wrap?

Denys Vlasenko vda.linux at googlemail.com
Thu May 14 14:39:17 UTC 2009


On Thu, May 14, 2009 at 12:24 AM, Rob Landley <rob at landley.net> wrote:
> 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.

Yes. bash suffers from the same problem.

> 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...

How to address it?

>  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

bbox has similar code in resize applet.

http://git.busybox.net/busybox/tree/console-tools/resize.c

Does it need robustify'ing btw?
Try running eval `resize`. Does it (a) work at all? and
(b) does it set LINES and COLUMNS?

Anyway. This trick can be used for (a) determining screen size
by moving cursor to the end (ESC [ 999 ; 999 H) and then
asking "where is the cursor now?", which solves "serial console
does not know its size" problem,
and (b) determining current cursor position by just asking
"where is the cursor now?", which solves "shell after echo -n blabla"
problem. Which problem of these two do you want to solve?

> 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.

Can be done. But parser would be confused by the two different usages.
What do you want to do, (a) or (b)?

> Note you probably only want to send that escape sequence if there _isn't_
> already input pending.

If terminal is not so dumb and it never intermixes this sequence
with real user input, we can just sit and wait for that code to show up
anytime.

> (Has the escape sequence parsing logic I tweaked in
> the VI code last year been genericized yet?)

Yes.

http://git.busybox.net/busybox/tree/libbb/read_key.c

> 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...

Basic sanity testing would be necessary in the parser, yes.
We do not want to find ourself in e.g.  -5x999999999 window.

--
vda


More information about the busybox mailing list