lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: lynx-dev Problem with ^Z suspending - so far...


From: Klaus Weide
Subject: Re: lynx-dev Problem with ^Z suspending - so far...
Date: Thu, 28 Jan 1999 08:07:35 -0600 (CST)

On Wed, 27 Jan 1999, Bela Lubkin wrote:
> Klaus Weide wrote:
> 
> > Problem II - wrong screen content
> > ---------------------------------
> > 
> > Job gets suspended, but then screen content (including cursor position) is
> > somehow wrong.  For example prompt may appear in middle of screen (for
> > lynx -show_cursor).
    [ ... ]
> > This is rather cosmetic, and probably unavoidable unless interactive shells
> > are changed to keep track of grandchildren, or a SIGTSTP handler is added
> > to the script that somehow makes it delay stopping until its child has
> > stopped.
> 
> I think this can be avoided, in a manner which avoids all four problems
> (you numbered them I, II, II', III).
> 
> Your current solution will help, but it has a race condition which will
> cause it to occasionally misfire -- and possibly, consistently misfire
> on some multiprocessor systems.

I am aware that I left a small window between determining
tcgetpgrp(STDIN_FILENO) and the tcgetattr() (in def_prog_mode) during
which the terminal might change ownership.  (Anything else?)

One way to detect that would be to repeat the tcgetpgrp after the
tcgetattr and throw away the result of the tcgetattr if we are now in
the background.  Another way (probably worse) would be to temporarily
install a small handler for SIGGTOU further down (instead of blocking
it) which does nothing much except detect that condition.

I agree that your solution below may be better for any given program;
OTOH a fix in the library benefits lots of programs automatically,
your approach requires changing each application program (that one
cares enogh about) separately.  I'd prefer the library fix even if
it's not perfect, if I had to choose.

Well I don't have to choose, one could do both.

> A stronger solution is for the job-control-aware program to establish
> itself as a separate pgrp, and make that the foreground group.  Then it
> will receive signals, but anything else in the session won't.  Then, in
> its stop-signal handler, it would need to cede control back to the
> parent (by changing the foreground pgrp, then sending it an appropriate
> sort of stop signal).  This is complex -- have to deal with situations
> where there is no parent (exec'd from a child of init), where the parent
> subsequently dies; also have to deal sensibly with children, both non-
> interactive (NSL_FORK child, gzcat, etc.) and interactive ('!' = SHELL).
> 
> Complex, but doable.  Shells do it.  You can run ash from bash from csh,
> run programs underneath that, job control them, and get sane results
> (usually).

Yeah but you don't usually run an interactive shell from a non-interactive
one; and if you do, you don't usually suspend the interactive shell
itself; and if you do that (bash has a "suspend" command), you end up with
a hung session.  Just pointing out that the situation is quite different.

> I've seen impassioned arguments in the past that the BSD job control
> design is a botch.  Up 'til now I'd never gotten so deeply involved with
> it.  I'm afraid I'm coming to agree.  :-(

I didn't know that this is "BSD job control" - are there alternatives?
Anyway, once I started looking closely, it's kind of surprising that
problems don't show up more often.

> In your new code:
> [ snip ] 
> This turns on some bits in mask;
> [ snip ]
> You can save a system call:
> 
> #ifdef SIGTTOU
>       (void)sigaddset(&mask, SIGTTOU);
> #endif
>       (void)sigprocmask(SIG_BLOCK, &mask, &omask);
> #ifdef SIGTTOU
>       sigttou_blocked = sigismember(&omask, SIGTTOU);
> #endif

Agreed.

Actually it might be ok to just leave SIGTTOU blocked (longer); I tried
to change the mask state for only the duration of the necessary calls,
to be conservative.

Btw. slang appears to always block various signals before any tcsetattr
calls, with

  sigprocmask(SIG_BLOCK, [INT QUIT TSTP TTIN TTOU], []) = 0

That looks like the other extreme of what ncurses does.  I am wondering
whether too much blocking sometimes creates problems.

   Klaus

reply via email to

[Prev in Thread] Current Thread [Next in Thread]