muller@sdcc10.ucsd.edu (Keith Muller) (10/29/89)
Subject: rn and rrn may wedge tty's on some BSD unix versions
Index: (r)rn/util.c (r)rn/final.c
Description:
Under some versions of UNIX with BSD job control, it may be
possible to wedge (r)rn in a state where it is stopped
on tty input (SIGTTIN) or tty output (SIGTTOU) and the tty is
still in the (r)rn's process group.
Repeat-By:
1) login under csh
2) run (r)rn
3) type control-z to suspend (r)rn
4) type bg to push (r)rn into the background
5) when (r)rn stops, then type fg to bring (r)rn into the foreground
Your terminal is now wedged. If you look at the tty from another
terminal you will see the rn in T state (stopped on SIGTTOU).
You can restore the tty to the csh by killing the rn with
a kill -9 from another terminal. (Of course why would anyone put
rn into the background???)
This has been observed on CCI, Vaxes running 4.3BSD-Tahoe, Pyramids,
and Sun 4's running SUNOS 4.0.1 and 4.0.3. Without going into
a long discussion, it probably will not occur with all machines
that provide BSD job control.
Fix:
Fix the signal handlers to catch SIGTTOU and SIGTTIN along with
SIGTSTP in final.c and util.c. Remove the handler for SIGCONT.
These fixes probably will not break anything on machines that do not
suffer from this problem.
Keith Muller
University of California, San Diego
muller@ucsd.edu
NOTE: YOUR LINE NUMBERS WILL BE DIFFERENT!
RCS file: RCS/util.c,v
retrieving revision 1.2
diff -c -r1.2 util.c
*** /tmp/,RCSt1017130 Sat Oct 28 12:49:31 1989
--- util.c Sat Oct 28 01:12:22 1989
***************
*** 49,55 ****
#ifdef SIGTSTP
sigset(SIGTSTP,SIG_DFL);
! sigset(SIGCONT,SIG_DFL);
#endif
if (shl != Nullch)
shell = shl;
--- 55,62 ----
#ifdef SIGTSTP
sigset(SIGTSTP,SIG_DFL);
! sigset(SIGTTOU,SIG_DFL);
! sigset(SIGTTIN,SIG_DFL);
#endif
if (shl != Nullch)
shell = shl;
***************
*** 88,94 ****
signal(SIGQUIT, qstat);
#ifdef SIGTSTP
sigset(SIGTSTP,stop_catcher);
! sigset(SIGCONT,cont_catcher);
#endif
return status;
}
--- 95,102 ----
signal(SIGQUIT, qstat);
#ifdef SIGTSTP
sigset(SIGTSTP,stop_catcher);
! sigset(SIGTTOU,stop_catcher);
! sigset(SIGTTIN,stop_catcher);
#endif
return status;
}
RCS file: RCS/final.c,v
retrieving revision 1.1
diff -c -r1.1 final.c
*** /tmp/,RCSt1017136 Sat Oct 28 12:49:53 1989
--- final.c Sat Oct 28 01:14:41 1989
***************
*** 28,34 ****
{
#ifdef SIGTSTP
sigset(SIGTSTP, stop_catcher); /* job control signals */
! sigset(SIGCONT, cont_catcher); /* job control signals */
#endif
sigset(SIGINT, int_catcher); /* always catch interrupts */
--- 34,41 ----
{
#ifdef SIGTSTP
sigset(SIGTSTP, stop_catcher); /* job control signals */
! sigset(SIGTTOU, stop_catcher); /* job control signals */
! sigset(SIGTTIN, stop_catcher); /* job control signals */
#endif
sigset(SIGINT, int_catcher); /* always catch interrupts */
***************
*** 140,150 ****
};
#endif
- #ifdef SIGTTOU
- #ifndef lint
- sigignore(SIGTTOU);
- #endif lint
- #endif
#ifdef DEBUGGING
if (debug) {
printf("\nSIG%s--.newsrc not restored in debug\n",signame[signo]);
--- 147,152 ----
***************
*** 186,192 ****
/* come here on stop signal */
int
! stop_catcher()
{
if (!waiting) {
checkpoint_rc(); /* good chance of crash while stopped */
--- 188,195 ----
/* come here on stop signal */
int
! stop_catcher(signo)
! int signo;
{
if (!waiting) {
checkpoint_rc(); /* good chance of crash while stopped */
***************
*** 195,231 ****
if (debug)
write(2,"stop_catcher\n",13);
#endif
! sigset(SIGTSTP,SIG_DFL); /* enable stop */
#ifdef BSD42
! sigsetmask(sigblock(0) & ~(1 << (SIGTSTP-1)));
#endif
! kill(0,SIGTSTP); /* and do the stop */
! }
! sigset(SIGTSTP,stop_catcher); /* unenable the stop */
! }
!
! /* come here on cont signal */
!
! int
! cont_catcher()
! {
! sigset(SIGCONT,cont_catcher);
! savetty();
#ifdef MAILCALL;
! mailcount = 0; /* force recheck */
#endif
! if (!panic) {
! if (!waiting) {
! #ifdef DEBUGGING
! if (debug)
! write(2,"cont_catcher\n",13);
! #endif
! noecho(); /* set no echo */
! crmode(); /* set cbreak mode */
! forceme("\f"); /* cause a refresh */
/* (defined only if TIOCSTI defined) */
! }
}
}
#endif
-
--- 198,221 ----
if (debug)
write(2,"stop_catcher\n",13);
#endif
! sigset(signo,SIG_DFL); /* enable stop */
#ifdef BSD42
! sigsetmask(sigblock(0) & ~(1 << (signo-1)));
#endif
! kill(0,signo); /* and do the stop */
! savetty();
#ifdef MAILCALL;
! mailcount = 0; /* force recheck */
#endif
! if (!panic) {
! if (!waiting) {
! noecho(); /* set no echo */
! crmode(); /* set cbreak mode */
! forceme("\f"); /* cause a refresh */
/* (defined only if TIOCSTI defined) */
! }
! }
}
+ sigset(signo,stop_catcher); /* unenable the stop */
}
#endif