[RFC, PATCH] new applet resize #2

Rob Landley rob at landley.net
Mon Sep 25 01:24:28 UTC 2006


On Sunday 24 September 2006 5:30 am, Bernhard Fischer wrote:
> >The purpose of this applet is to run from the command line?  Or are we 
> 
> It's purpose is to be run interactively (only, i'd say).
> 
> >encouraging people to have it in their /etc/profile?  If they start typing 
> >before their /etc/profile runs (or they "echo command | sh", don't we have 
> >the same problem with bbsh interactive mode, where it shouldn't do this if 
> >there's already data waiting on stdin?  (Or should it discard any data 
> >waiting on stdin?)
> 
> I don't understand what you're saying here. Please explain?

People who are going to be running a serial console a lot are going to be 
tempted to stick this in the /etc/profile or ~/.shellrc or some such, so that 
the shell they run on the serial console gets set up correctly automatically.

We have two ways of dealing with this:

1) Put a big warning sign in its docs, ala "This uses in-band signalling, so 
typing anything between the time you run it and the time it returns could 
interfere with it functioning, and putting it in /etc/profile could have 
nasty side effects."  This wouldn't actually help matters because nobody ever 
reads the docs, but it would give us something to point at and feel smug 
about when people come to the list for help.

2) Try to make it work when it gets run from ".shellrc".

Nontrivial, but possible.  At least it's possible to guard against it doing 
_stupid_ things, unfortunately by making it fail easily.

My first instinct was to wire it into the darn shell (since we already have a 
set of tests for "interactive mode" anyway, which are about 2/3 of the tests 
we'd need to do this safely).  But if there's an applet that already does 
this, I want to also implement that applet as well, which means I need to 
stick this functinality in libbb.

I've got a number of unanswered questions.  For example, when this fails 
(reads garbage, perhaps) should it print a warning similar to the 
existing "Job control turned off" warning?  ("Terminal probing failed, 
run 'resize' to try again." except that's darn verbose and a waste of bytes.  
Sigh...)

How much of the "interactive mode" tests should move from bbsh into the 
libbb/resize_probe_thing()?  (For example: don't do this if stdin and stdout 
don't point to the same device, but does that device have to be a _terminal_?

I agree that 10 seconds is too long of a timeout (enough to annoy humans).  
I'm thinking 2 is probably plenty, maybe 3 for paranoia, but if your xterm 
gets swapped to disk to swapped to disk I'm ok with this failing (see 
possible warning message, above).

I'm 90% certain that this should stay separate from 
get_terminal_width_height(), but it's darn tempting to at least put them next 
to each other.

Did I mention I spent a decent chunk of the week before Bruce cropped up 
researching terminal control stuff?  (I now have a tentative understanding of 
the difference between sessions and process groups.  Yes, I believe I now 
understand how to make getpid(), setsid(), setpgid(), and tcsetpgrp() play 
nice with each other in the context of vfork() resetting signal handlers 
before calling exec()!  In that context, using the ansi probe as a fallback 
for a zero by zero terminal makes perfect sense to me, which probably means 
it drove me insane learning it...

And then Bruce showed up and the stress turned my brain to jello.  Don't ask 
me how "The issue is resolved now!" turned into a teleconference with me, 
Bruce, Erik, and the SFLC monday evening.  Attracting Bruce's attention is 
like getting a terminal disease, it's never _cured_ you just go into 
_remission_ for a while.  However, the alternatives are "see this through 
until one of us dies of old age, and I'm younger than he is" or "Walk away 
from BusyBox entirely".  And I've put years into BusyBox and accepted a lot 
of responsibility for it which I take quite seriously.

To be clear, "Bruce getting his way" and "Me walking away from the current 
codebase" are equivalent options.  If he somehow managed to prove that I 
couldn't put out GPLv2 only versions of the project (which he can't), I would 
stop working on the current code base completely.  Probably I'd start a new 
one from scratch.  It would actually only take me about a year to reimplement 
the 2/3 of it I actually use.

In the meantime, lots of naps and long soothing walks, to make at least _some_ 
off the headaches go away...

> >And _if_ we do this, I'd like to re-use the code that bbsh is using to do 
this 
> >probing for interactive mode, rather than having two implementations in the 
> >tree.  I believe I _said_ that.
> 
> bbsh doesn't have that code AFAICS.

The copy that's currently in the tree doesn't, no.  But:

http://busybox.net/lists/busybox/2006-September/024571.html

My current version's gone all complicated again because I tried to add 
terminal control, pipe/redirect support, and quote parsing all at once and it 
got snarled up.  (Sigh.  Trying to code while stressed out of my mind by 
Bruce eruptions isn't helping, either.  And I feel guilty for not keeping up 
with the review of Denis's patches either: there are three things I strongly 
suspect he's broken and haven't gone and tested because then I'd have to fix 
them.  This is the first time all weekend I've gotten an uninterrupted hour 
and a half to sit down and code, and I've gotten _three_ phone calls during 
it already.)

I'm pondering breaking one of the three out and patching it onto the in-tree 
version just to flush some of the complexity.  Terminal control is the 
obvious candidate there.

> You don't seem to want to collaborate with anybody wrt bbsh.

It's not quite that simple.  I have put in a _lot_ of prep work for bbsh.  You 
can too if you'd like, but it took _me_ most of a year.  In order to get 
ready to do bbsh, I have so far read:

1) The lash.c code (I printed it out and read it all, beginning to end, at 
least three times; I've carried around a copy in my backpack for months now).  
Pay special attention to the things it does wrong, such as:

landley at driftwood:~/busybox/busybox$ touch "one two"
landley at driftwood:~/busybox/busybox$ ./busybox lash
~/busybox/busybox $ ls one*
ls: one: No such file or directory
ls: two: No such file or directory

2) Skim the hush and msh code.  Don't have to be too thorough about it, just 
figure out approximately what features they've got.

3) Read the SUSv3 shell language specification.  (Again, printing out a copy 
and carrying it around everywhere you go for weeks seems to help, and I'm not 
all the way through it yet, I go through two pages and then have to stop and 
think for half an hour, and then write down strange notes about the 
ramifications, such as the fact that "echo -ne 'false &\\\n&echo hello' | sh" 
has to become "false && echo hello" and so shouldn't print anything because 
the \ eats the newline _first_ and the && token is parsed _afterwards_ and 
yes I have to test for that.  Oh, and you can't just look for \ at the end of 
the line before parsing your way up to that: try "ls -l # \".  Parsing is 
very context-sensitive and only makes sense front to back...)

You might also want to look at the SUSv3 shell command definition, which is 
not the same thing as the language specification.

4) Read the bash man page.  (Print it out and add it to the big three ring 
binder you carry around with you.  I'm still only at the "selected bits of it 
made sense" stage.  Also the bash FAQ and the advanced bash programming 
guide, although that adds another 300+ pages and I haven't printed 'em out 
yet because I'd need another ream of paper and a second binder.  But I've got 
the pdfs on my laptop.)

5) Read about the historical bourne, korn, and c shells.  (I hate to recommend 
the wikipedia articles, but it's a start and they link to other stuff.  "csh 
programming considered harmful" has a few interesting bits.)

6) Ponder the really weird corner cases of parsing, like embedded nul bytes in 
the output of backquote commands.  Check to see what bash does.  Take more 
notes.  (Pop quiz: why is having two spaces between "one" and "two" in
  echo "$(echo "one  two")"
a much better test then just having one space there?)  

7) Break the whole mess down into functional sub-units like job control and 
terminal control, and then ponder each of _their_ weird corner cases, like 
what happens when you type "read i" on the command line and hit ctrl-z?  
Notice that the read command is like cd and exit: it can't be a background 
process because the point of the thing is to set an environment variable, and 
that environment variable would go away when the background process did.  
(Other fun things to try ctrl-z with include "sleep 5 && ls | sort", "sleep 
5 ; ls | sort", and of course "sleep 5 | wc".  Then go back through the specs 
and figure out how much of that behavior is actually _required_, and how much 
is an implementation idiosyncrasy.  That's still a todo item of mine.)

8) Work out how the functional sub-units interact with each other.  Can quote 
parsing and pipes/redirects be separated so you can arbitrarily disable one 
but not the other?  What features require a union of otherwise orthogonal 
functional groups?  (Look at ctrl-z: You need both job control and terminal 
control for that, but job control and terminal control shouldn't depend on 
each other because you can detach processes with & in a shell script and you 
should be able to kill things with ctrl-c even when you can't background 
them.)

According to http://busybox.net/~landley/notes.html my first "hello world" 
version of bbsh was November 7, 2005, but that wasn't when I started on it.  
I'd been studying what was required for a while.  The October 14 entry 
mentions my intention to do it, but I'd been poking at it before then.  The 
reason for the big gap between last November and when I put the "tiniest 
possible shell I can do" into the tree was that my early attempts at this 
only proved to me how little I knew about the problem space, and I had to go 
study lots and lots and lots.

We have four shells in the tree right now.  "Doing a shell" is not a major 
limiting factor.  I want to do it _right_, so we can have _fewer_ shells..

> That 
> resize applet serves a unique, established purpose that shouldn't be
> hindered by eventual progress you as a single person achieve with bringing
> bbsh forward.

If we're going to have it in the tree, we should do it right.

And I'd already added equivalent functionality to bbsh (remember how I worked 
out a functional probe string without actually seeing the other code), and 
when I found out that resize was an existing applet I wanted to generalize 
that code.

I also don't know why the resize applet you submitted was resetting terminal 
parameters _before_ doing the probing.

> >Also, I'd rather not add new code into the tree with "or later" and then 
have 
> >to go back and remove it as I get around to making the license notices 
> >uniform.
> 
> I would have removed the or later in a day or two, if the applet was
> still in the tree

I meant to put the darn thing back into the tree yesterday, but the SFLC 
scheduled a teleconference they want both me and Bruce on, and I got another 
headache and had to go lie down.  (I'll be _so_ happy when Bruce finally goes 
back to his crypt.  This is _not_ good for my health.)

Then this morning my laptop decided to do a fresh reboot rather than 
resume-from-suspend, so I lost my open window and have to track down the 
patch again.  (Software suspend on Ubuntu 6.06 is _really_ flaky.  I think 
the problem is that my laptop's hard drive has an onboard buffer that only 
sometimes flushes the last block before the power goes off, and when it 
doesn't the swap partition has all the resume data in it but doesn't have the 
start of the partition marked as a suspend image instead of normal swap.  I'd 
blame the hardware, except that earlier versions of ubuntu didn't do this 
(they had _different_ bugs).  I think it's actually the kernel missing a 
flush somewhere in the suspend to disk path.)

No, I haven't built my own kernel for my laptop.  Last time I tried it, 
getting the ipw2200 firmware loading to line up again was enough of a pain I 
gave up, and I've been way too busy to get back to it...

But mostly?  Weekend.  Tired.  Sleeping muchly, visiting Ikea, reading... ok, 
reading the OLS2006 proceedings but _also_ reading a fluffy Wen Spencer book 
about elves and dragons and such.

Rob
-- 
Never bet against the cheap plastic solution.



More information about the busybox mailing list