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: Bela Lubkin
Subject: Re: lynx-dev Problem with ^Z suspending - so far...
Date: Wed, 27 Jan 1999 14:34:20 -0800

Klaus Weide wrote:

[lots of good research...]

> 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 happens (under the Preconditions) whenever the SIGTSTP handler would
> generate some output - it either arrives in the wrong order, or, in
> connection with Problem I, not at all.
> 
> Let's denote with L the character output that is (or would be) generated by
> the application's handler, and S the interactive shell's output (status and
> prompt), and + means order in time or concatenation (Think L=lynx or less,
> S=shell).  With ncurses, L is typically some escape sequences for
> positioning the cursor on the last screen line, possibly in connection
> with a rmcup string.
> 
> Wanted: L + S
> 
> Actual: S + L       (SIGTTOU ignored or blocked, or -tostop)
>         S           (SIGTTOU stops, and tostop)
> 
> 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.

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

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

In your new code:

>       (void)sigprocmask(SIG_BLOCK, &mask, &omask);

This turns on some bits in mask;

> +#ifdef SIGTTOU
> +     sigttou_blocked = sigismember(&omask, SIGTTOU);
> +     if (!sigttou_blocked) {

Then, if the previous mask didn't have SIGTTOU masked, ...

> +         (void)sigemptyset(&mask);
> +         (void)sigaddset(&mask, SIGTTOU);
> +         (void)sigprocmask(SIG_BLOCK, &mask, NULL);

... you further add that bit.

> +     }
> +#endif

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

(basically the same as you do in the SIG_UNBLOCK part).

Tom Dickey wrote:

> > This works for me to solve problems I and III (see my other message, 
> > http://www.flora.org/lynx-dev/html/month0199/msg00737.html). 
> >  
> > Tom, can you look at this for including in ncurses?  I'm sure it needs 
> > at least some ifdefs. 
> 
> I've been following this thread (and aside from applying other people's
> patches, seems to be the top item on lynx+ncurses for the moment).  I'll
> have to ifdef it, probably (not all platforms have the tcgetpgrp, I assume).

You will probably have to #ifdef it a lot; though, in theory,
distribution of tcgetpgrp() should exactly match distribution of
SIGTTOU, since they are separate parts of the implementation of the same
mechanism, job control.

In fact, perhaps the way to do it is for configure to ask "are all of
these pieces present?"  If so, #define WE_HANDLE_JOB_CONTROL.  If not,
#undef it and don't do any of this code, let the shell deal with it.
That means: don't trap any JC signals at all; be completely unaware of
them.  In practice, this means that ncurses handles its own job control
on most systems; on a few, with partial implementations, the shell
handles it; and on older ones with no job control, nobody handles it
because it doesn't exist...

>Bela<

reply via email to

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