[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: lynx-dev Problem with ^Z suspending
From: |
Kari E. Hurtta |
Subject: |
Re: lynx-dev Problem with ^Z suspending |
Date: |
Wed, 27 Jan 1999 10:08:09 +0200 (EET) |
Klaus Weide:
> [ On a different tangent: ]
> > Well... Lynx already forks a lot due to NSL_FORK. It might be better if
> > there were two always-running coprocesses, one to do lookups and one to
> > interact with the user.
>
> Or like squid with its external dnsserver processes... (they communicate
> via sockets.)
>
> > The interactive one could very well be the
> > child, in which case it's no big deal to also-by-the-way make it its own
> > pgrp.
>
> Would confuse parent interactive shell, which wouldn't know to kill it
> with SIGHUP on exit etc.
Well, that other process what is forked (to keep origianl process group;
or which way you arrange it), will get that SIGHUP [**] (because it is on
process group for which shell knows about). [*]
And it is anyway good to check errors when read from terminal
(it will fail when terminal is closed on exit).
/ Kari
Please ignore rest....
This is going to to detailed.
And I do not know was that best method...
And there is really many not so nice details.
[*] Actually that my program (from some years ago) when was suspending
itself put it first to original process group.
void handle_sigtstp(int sig) { /* User have pressed Ctrl-Z */
/* In SUNOS5 we need block SIGTTOU */
if (DEBUG_SIGNAL)
print_error2(P_DEBUG,"Got SIGTSTP (sig=%d)", sig);
reset_terminal_state(); /* Give original terminal characters */
flush_buffer(0); /* and print it to terminal */
set_caller_ttystate();
deliver_signal(sig); /* Now my callers turn */
stop_me();
set_pager_ttystate();
need_redraw = 1;
if (DEBUG_SIGNAL)
print_error2(P_DEBUG,"Done SIGTSTP (sig=%d)", sig);
}
Where:
void set_caller_ttystate(void ) {
if (!termios_set) return;
again1:
if (-1 == tcsetattr(terminal,TCSADRAIN,&tty_origstate)) {
int code = errno;
if (EINTR == code) goto again1;
print_error2(code,
"(%P) set_caller_ttystate/Can't restore tty state for
/dev/tty");
} else tty_state_set = 0;
if (have_group) {
again2:
if (-1 == tcsetpgrp(terminal,oldgroup)) {
int code = errno;
if (EINTR == code) goto again2;
print_error2(code,
"(%P) set_caller_ttystate/Can't change terminal group to %d",
oldgroup);
} else if(DEBUG_SIGNAL || DEBUG_TERM)
print_error2(P_DEBUG,"Terminal group is now restored to %d",oldgroup);
}
}
and:
static void stop_me(void) {
if (have_group && mypid != oldgroup) {
if (-1 == setpgid(mypid,oldgroup)) {
int code = errno;
print_error2(code,
"SUSPENDING CANCELED!\n(%P) stop_me/Can't join again my old
group = %d",
oldgroup);
/* IF we now stop, we stuck when kehpager is resumed !!! */
return;
} else if (DEBUG_SIGNAL || DEBUG_TERM)
print_error2(P_DEBUG,"Joined to old terminal group %d",oldgroup);
}
if (DEBUG_SIGNAL)
print_error2(P_DEBUG,"Sending SIGSTOP to myself");
kill(mypid,SIGSTOP);
if (DEBUG_SIGNAL)
print_error2(P_DEBUG,"Woked up from SIGSTOP");
if (have_group && mypid != oldgroup) {
if (-1 == setpgid(mypid,mypid)) {
int code = errno;
print_error2(code,
"(%P) stop_me/Can't recreate again my new group = %d (my
pid)",
mypid);
have_group = 0;
} else if (DEBUG_SIGNAL || DEBUG_TERM)
print_error2(P_DEBUG,"Joined to new terminal group %d (my pid)",mypid);
}
}
and:
static void deliver_signal(int sig) {
if (!have_group || mypid == oldgroup) return;
if (-1 == kill(-oldgroup,sig)) {
int code = errno;
print_error2(code,"(%P) deliver_signal/Can't deliver signal %d to group %d",
sig,oldgroup);
} else if (DEBUG_SIGNAL)
print_error2(P_DEBUG,"Signal %d delivered to group %d",sig,oldgroup);
}
And:
void set_pager_ttystate(void) {
if (!termios_set) return;
check_terminal_group();
if (have_group) {
sigset_t oldmask,blockmask;
sigemptyset(&blockmask);
sigaddset(&blockmask,SIGTTOU);
if (-1 == sigprocmask(SIG_BLOCK,&blockmask,&oldmask)) {
int code = errno;
print_error2(code,"(%P) set_pager_ttystate/Can't block SIGTTOU");
} else {
again0:
if (-1 == tcsetpgrp(terminal,mypid)) {
int code = errno;
if (EINTR == code) goto again0;
print_error2(code,
"(%P) set_pager_ttystate/Can't change terminal group "
"to %d (my pid)",
mypid);
} else if(DEBUG_SIGNAL || DEBUG_TERM)
print_error2(P_DEBUG,"Terminal group is now changed to %d (my pid)",
mypid);
if (-1 == sigprocmask(SIG_SETMASK,&oldmask,NULL)) {
int code = errno;
print_error2(code,"(%P) set_pager_ttystate/Can't unblock SIGTTOU");
}
}
}
again1:
if (-1 == tcsetattr(terminal,TCSADRAIN,&tty_state)) { /* when output is wrote
*/
int code = errno;
if (EINTR == code) goto again1;
print_error2(code,"(%P) set_pager_ttystate/Can't change tty state of
/dev/tty");
} else tty_state_set = 1;
get_winsize(1);
}
And this is nasty part. Do not change terminal process group if
you are not currently on foregroup group of terminal: :-)
static void check_terminal_group(void) {
int cgroup;
again:
while (oldgroup != (cgroup = tcgetpgrp(terminal))) {
if (-1 == cgroup) {
int code = errno;
if (EINTR == code) goto again;
terminal_have_lost = 1; /* default */
print_error2(code,"(%P) check_terminal_group/Can't get current group");
QUIT_pager(0);
}
if(DEBUG_SIGNAL)
print_error2(P_DEBUG,"Terminal group = %d, my group = %d. Suspending...",
cgroup,oldgroup);
kill(mypid,SIGSTOP); /* wait that I am in foreground */
if(DEBUG_SIGNAL)
print_error2(P_DEBUG,"Wake up");
}
}
[**]
static void friend_have_died(int res) {
if (allow_dead) return;
print_error2(P_NOTIFY,"(%P) Reserver process (%d) died - exiting (%d)...",
res,mypid);
myfriendpid = 0;
reset_terminal_state(); /* give original terminal characters */
set_caller_ttystate();
close_files();
close_terminal();
if (DEBUG_SIGNAL)
print_error2(P_DEBUG,"Exit ...");
kill(mypid,SIGTERM); /* Kill me */
exit(6);
}
- lynx-dev Problem with ^Z suspending, Klaus Weide, 1999/01/22
- Re: lynx-dev Problem with ^Z suspending, Bela Lubkin, 1999/01/24
- Re: lynx-dev Problem with ^Z suspending, Bela Lubkin, 1999/01/24
- Re: lynx-dev Problem with ^Z suspending, dickey, 1999/01/24
- Re: lynx-dev Problem with ^Z suspending, Henry Nelson, 1999/01/24
- Re: lynx-dev Problem with ^Z suspending, Bela Lubkin, 1999/01/26