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