Makeing the subshell reliable

Pavel Tsekov ptsekov at gmx.net
Thu Jul 20 09:00:58 UTC 2006


On Wed, 19 Jul 2006, Oswald Buddenhagen wrote:

> On Wed, Jul 19, 2006 at 04:58:16PM +0300, Pavel Tsekov wrote:
>> On Tue, 18 Jul 2006, Oswald Buddenhagen wrote:
>>>> Shall we keep the prompt in this case ?
>>>>
>>> i think it would be logical.
>>
>> But then we shall face the same problems. I mean it is not different
>> from what we do now. The only difference is that the output will go
>> to the panel directly and no Ctrl+O would be necessary.
>>
> yup, that's why i said that we have to fix it first in any case. ;)

So we are back from where we've started.

> some thoughts regarding idleness detection. the shell can be in three
> states: idle (just output prompt), busy (after any input until we hit
> enter or make it declare itself idle again (ctrl-c)) and inactive (after
> enter in non-inactive state, i.e., executing command). in busy state,
> ctrl-l has known semantics: it causes all three supported shells to send
> us a clearscreen followed by a repaint. when we try to submit a command
> but find the shell in busy state, we can issue ctrl-l and capture the
> output (i.e., don't display it) and compare it with the prompt we
> received. if it is equal, we declare that the shell is in fact idle and
> submit the command.

> regarding the problem with freebsd, i have to ask again. is this related
> to http://mail.gnome.org/archives/mc-devel/2002-August/msg00022.html (how
> i initially assumed)? if no, i have to request more info ...

It is a variant of that problem. Apparently the fix (flush pending 
input) was not sufficient. If you think about it and understand how
the subshell works it is clear that it won't help much. Ok, now let
me describe the FreeBSD problem - I did already but I'll do again:

1) Start MC (subshell enabled)

2) Type a command which takes time to complete on the
MC command prompt (ls -lR /some/big/dir)

3) While the command is running hit Enter

4) After the command terminates exit MC (F10)

If you follow this steps you'll get a stale subshell after
MC exits. This happens because the subshell is stopped at
the time that MC exits and the normal SIGHUP processing
(pty hangup) cannot happen. I'll explain why the subshell
remains stopped below.

A major part of the subshell feature is a function called
feed_subshell() - it does several things:

1) Sends input typed by the user to the subshell over the
subshell pseudo terminal

2) Sends output produced by the subshell back to the user

3) Retrieves the current directory of the subshell after
command termination

4) Waits for the termination of a command executed in the
subshell

For 4 to work it is arranged that the subshell stops itself
with SIGSTOP before it prints its prompt (PROMPT_COMMAND in
bash, precmd for zsh and tcsh). Before the subshell stops
it prints its current directory to a certain file descriptor
on which MC listens for input. So when input comes on this
file descriptor MC suspends itself until the arrival of
SIGCHLD indicating that the subshell stopped. When MC is
awakened it awakes the subshell (SIGCONT) and exits
feed_subshell().

So, now you should understand that the subshell is stopped
each time it has to print its prompt. The FreeBSD problem
described above happens because the Enter (step 3) gets to
the subshell and is executed. Since this happens outside
of feed_subshell() processing there is noone to revive the
subshell after it stops itself.

I hope this explanation helps. If you have questions, please,
ask. There are many ways to attack this problem but if we are going
to fix it we have to choose the right one. There are certain
flaws in this scheme  - I mean codewise. For example I think
the retrieval of the current dir should happen after the
acknowledgement that the subshell has stopped. There are others too.




More information about the mc-devel mailing list