Re: tty state not restored after restarted stopped job

2018-05-07 Thread G.raud Meyer
On Fri, Apr 27, 2018 at 05:23:36PM +, Thorsten Glaser wrote:
> From looking at the code, I donbt think it entirely correct.
> Therebs a tty_hasstate, and one of the comments around it says
>   /*
>* Only restore tty settings if job was originally
>* started in the foreground. Problems can be
>* caused by things like 'more foobar &' which will
>* typically get and save the shell's vi/emacs tty
>* settings before setting up the tty for itself;
>* when more exits, it restores the 'original'
>* settings, and things go down hill from there...
>*/
> although, slightly below, it also says
>   /*-
>* Don't use tty mode if job is stopped and
>* later restarted and exits. Consider
>* the sequence:
>*  vi foo (stopped)
>*  ...
>*  stty something
>*  ...
>*  fg (vi; ZZ)
>* mode should be that of the stty, not what
>* was before the vi started.
>*/
> which matches your description, so itbs probably merely incomplete
> (or in the Job control subsection?).
> 
> *looks* band the state of the terminal is saved or restored when a
>foreground job is stopped or restarted, respectivelyb
> it saysb& perhaps we should reword this slightly?
> 
> 
> Ibve now moved the new subsection *below* the one on job control and
> removed the tty stuff from the job control one, to have it all in one
> place. The wording is currently like this:
> 
>   Terminal state
>  The state of the controlling terminal can be modified by a command exe-
>  cuted in the foreground, whether or not job control is enabled, but the
>  modified terminal state is only kept past the job's lifetime and used for
>  later command invocations if the command exits successfully (i.e. with an
>  exit status of 0). When such a job is momentarily stopped or restarted,
>  the terminal state is saved and restored, respectively, but it will not
>  be kept afterwards. In interactive mode, when line editing is enabled,
>  the terminal state is saved before being reconfigured by the shell for
>  the line editor, then restored before running a command.
> 
> I think this matches our understanding of the code; if not, please feel
> free to enter further comments into this discussion. The same goes for
> what the code actually does; with it being documented like this, are you
> happy with it?

It surprised me that even when job control is disabled, only a
"foreground" (as viewed by the shell) job can change the terminal state.
If the job does not get its own process group, how come it can't modify
the terminal state?

The following shows that a "background" command can change the terminal
state (since stdin is redirected to /dev/null for background commands,
either pass "-f /dev/tty" to stty or redirect stdin):

---
$ stty intr ^C; mksh -c 'stty intr ^G   The state of the controlling terminal can be modified by a command exe-
-  cuted in the foreground, whether or not job control is enabled, but the
-  modified terminal state is only kept past the job's lifetime and used for
+  cuted in the foreground when job control is enabled or by any command
+  when job control is disabled, but the
>  modified terminal state is only kept past the job's lifetime and used for
>  later command invocations if the command exits successfully (i.e. with an
>  exit status of 0). When such a job is momentarily stopped or restarted,
>  the terminal state is saved and restored, respectively, but it will not
>  be kept afterwards. In interactive mode, when line editing is enabled,
>  the terminal state is saved before being reconfigured by the shell for
>  the line editor, then restored before running a command.

-- 
G.raud


Re: tty state not restored after restarted stopped job

2018-05-07 Thread G.raud Meyer
On Sat, Mar 31, 2018 at 09:36:23PM +, Thorsten Glaser wrote:
> Hi,
> 
> I sometimes have weird tty state even after a process finished;
> this is mostly mpg123 running in foreground, so no backgrounding
> involved. When I then press Enter, the tty is back to normal
> state; is that true for your scenario too?

Typing ENTER does not change anything in my case.  But the tty is not in
an unforeseen state: it is just that after the command finishes
(successfully) if it has changed the tty state, this state is recorded
(and not reset to the value before it started) only if the job has not
been stopped, which I found susrprising.

I wondered if mksh records the stopping explicitely or if it is just a
side-effect of the code that does not keep the tty state after a failed
command (ends with non zero status or killed by SIGQUIT etc.).

> I didnbt find the underlying issue yet. If anyone can jump in
> with more debugging, or perhaps patches, Ibd be glad.

First one should know what is the correct behaviour.  The feature of
discarding tty changes after a failed command is related to job control
but it is not documented and not standard as neither bash nor ksh do
the same.  What makes sense is to discard the tty state after a
killed command as bash and ksh do.  After a failed command I don't think
it is necessary but it can be considered a safe choice.

Before a patch fixing the strange case of a "successful but temporarily
stopped job has failed" it would be good to document the feature (and
the bug, if it is one).

PS. bash has the same "bug", which can be tested with the following
command to circumvent the lack of tty state restoration when restarting
a job:
```
$ sh -c 'stty; sleep 2; stty; stty intr ^G; stty'
$ stty intr ^C; stty; sh -c 'stty intr ^G; sleep 2; stty; stty intr ^G; stty'
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
^Z
[1]+  Stopped sh -c 'stty intr ^G; sleep 2; stty; stty intr ^G; 
stty'
$ fg; stty
sh -c 'stty intr ^G; sleep 2; stty; stty intr ^G; stty'
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
speed 38400 baud; line = 0;
intr = ^G;
-brkint -imaxbel iutf8
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
```


Re: tty state not restored after restarted stopped job

2018-04-27 Thread Thorsten Glaser
Hi again,

>Thinking a bit more about this, I found a valid reason not to keep the
>terminal state after a restarted job exits (successfully): the tty
>state in which that job was started can be obsolete at the time it is
>restarted because the tty state may have been modified while the job was
>stopped (or running in the background).

good thinking.

>It would be a rare case where mksh is more "advanced" than ksh if the
>behaviour is intentional.

This is all from pdksh/oksh, so… ;-)

>I join a patch that adds a manage subsection "Terminal state" explaining
>how to change the terminal state and describing the exception for
>temporarily stopped jobs (and mentioning that the line editing
>code saves/restores the terminal state too).  The saving/restoring of
>the tty state for stopped/restarted jobs is already documented in the
>subsection "Job control".

From looking at the code, I don’t think it entirely correct.
There’s a tty_hasstate, and one of the comments around it says
/*
 * Only restore tty settings if job was originally
 * started in the foreground. Problems can be
 * caused by things like 'more foobar &' which will
 * typically get and save the shell's vi/emacs tty
 * settings before setting up the tty for itself;
 * when more exits, it restores the 'original'
 * settings, and things go down hill from there...
 */
although, slightly below, it also says
/*-
 * Don't use tty mode if job is stopped and
 * later restarted and exits. Consider
 * the sequence:
 *  vi foo (stopped)
 *  ...
 *  stty something
 *  ...
 *  fg (vi; ZZ)
 * mode should be that of the stty, not what
 * was before the vi started.
 */
which matches your description, so it’s probably merely incomplete
(or in the Job control subsection?).

*looks* “and the state of the terminal is saved or restored when a
 foreground job is stopped or restarted, respectively”
it says… perhaps we should reword this slightly?


I’ve now moved the new subsection *below* the one on job control and
removed the tty stuff from the job control one, to have it all in one
place. The wording is currently like this:

  Terminal state
 The state of the controlling terminal can be modified by a command exe-
 cuted in the foreground, whether or not job control is enabled, but the
 modified terminal state is only kept past the job's lifetime and used for
 later command invocations if the command exits successfully (i.e. with an
 exit status of 0). When such a job is momentarily stopped or restarted,
 the terminal state is saved and restored, respectively, but it will not
 be kept afterwards. In interactive mode, when line editing is enabled,
 the terminal state is saved before being reconfigured by the shell for
 the line editor, then restored before running a command.

I think this matches our understanding of the code; if not, please feel
free to enter further comments into this discussion. The same goes for
what the code actually does; with it being documented like this, are you
happy with it?

Thanks,
//mirabilos (still ill at home, but decided to tackle some TODO items)
-- 
Yay for having to rewrite other people's Bash scripts because bash
suddenly stopped supporting the bash extensions they make use of
-- Tonnerre Lombard in #nosec


Re: tty state not restored after restarted stopped job

2018-04-01 Thread Thorsten Glaser
G.raud Meyer dixit:

>First one should know what is the correct behaviour.  The feature of
[…]
>Before a patch fixing the strange case of a "successful but temporarily
>stopped job has failed" it would be good to document the feature (and
>the bug, if it is one).

I honestly don’t know.

It is desirable to be able to change all sorts of terminal state
with stty, so *some* not-resetting and/or saving is desirable.
On the other hand, the editor needs a certain state, too.

Basically, we need to not break the scenarios:

$ stty something; some other command
$ ← back to the line editor

(fully)

$ stty something
$ some other command ← back to the line editor

(partially? OTOH the line editor can cope with a LOT of states)

We also want the line editor to work.

It gets more complicated when backgrounded jobs come
into play. As I said, I honestly have absolutely no
idea…

Comparing this with, say, the last pdksh release,
would be a start: did it do the exact same thing,
and, if not, why the differences.

bye,
//mirabilos
-- 
Solange man keine schmutzigen Tricks macht, und ich meine *wirklich*
schmutzige Tricks, wie bei einer doppelt verketteten Liste beide
Pointer XORen und in nur einem Word speichern, funktioniert Boehm ganz
hervorragend.   -- Andreas Bogk über boehm-gc in d.a.s.r


tty state not restored after restarted stopped job

2018-03-31 Thread G.raud Meyer
In the first case, the command modifies the tty state and the state is
kept for the following commands.

In the second case, the command that modifies the tty state is
interrupted, then when restarted the tty state is restored for it but
when it finishes the tty state is reset to the default again, which is
not consistent with the first case.

Is this a bug as I think it is?

``` 1
$ stty intr ^C; stty; sh -c 'stty intr ^G; sleep 2; stty'; stty 
  
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
speed 38400 baud; line = 0;
intr = ^G;
-brkint -imaxbel iutf8
speed 38400 baud; line = 0;
intr = ^G;
-brkint -imaxbel iutf8
```

``` 2
$ stty intr ^C; stty; sh -c 'stty intr ^G; sleep 2; stty'; stty 
  
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
^Zspeed 38400 baud; line = 0;
-brkint -imaxbel iutf8
[1] + Stopped  \sh -c "stty intr ^G; sleep 2; stty" 
$ fg; stty  
  
\sh -c "stty intr ^G; sleep 2; stty" 
speed 38400 baud; line = 0;
intr = ^G;
-brkint -imaxbel iutf8
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
```

PS. ksh saves the tty state when a job is stopped, restored it when it
is restarted, and keeps the modified state when the job finishes.  bash
resets a default when a job is stopped but does not save the tty state
it seems.