🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Ray Moody Wed, 26 Jul 1989 07:59
Extremely obnoxious bash bug (hangs terminals dead).
#385
Author: Ray Moody
Date: Wed, 26 Jul 1989 07:59
90 lines
3338 bytes
    Bash can hang your terminal...

    If a SIGINT occurs inside fork we will eventually call readline
(not right away as the signal is temporarly blocked).  We might be in
readline when the child changes the terminals process group.

    The child dies with the SIGINT signal.  Flush_child is called.
Flush_child calls kill to process the signal.  Rl_signal_handler is
called.  Rl_deprep_terminal is called.  Ioctl(TIOCSETN) is called.
Since the terminal no longer belongs to bash, a TTOU signal is posted
by the kernel. Rl_signal_handler gets called again.
Rl_deprep_terminal gets called again.  Ioctl(TIOCSETN) gets called
again.  A TTOU signal is posted again, but it is blocked.  Ioctl will
then wait for the terminal to be given back to bash, but this is never
going to happen.  You will have to log onto a different terminal and
kill off bash.

    Whew!

    You can reproduce this bug best when fork takes much time.  This
happens when bash is big and swapped out (use hostname completion on a
big /etc/hosts, and then let bash sit idle for a while and run some
huge programs).  You might also try overloading your swap disks.

								Ray
-------------------------------------------------------------------------------
RCS file: RCS/jobs.c,v
retrieving revision 1.2.1.1
diff -c -r1.2.1.1 jobs.c
*** /tmp/,RCSt1027287	Wed Jul 26 02:57:26 1989
--- jobs.c	Wed Jul 26 02:54:00 1989
***************
*** 612,617
  	  if (!pipeline_pgrp)	/* Then this is the first child. */
  	    pipeline_pgrp = getpid ();
      
  	  /* You must give the tty away before you set the process group,
  	     and you must do these things only in the child.  Otherwise,
  	     race conditions can occur. */

--- 612,624 -----
  	  if (!pipeline_pgrp)	/* Then this is the first child. */
  	    pipeline_pgrp = getpid ();
      
+ 	  /* Fixed by Ray Wed Jul 26 02:36:21 EST 1989
+ 	     We restore our sigmask before we change the terminal process
+ 	     group because we don't want to change it if we got a SIGINT
+ 	     while we were in fork. (If we change it, readline will be
+ 	     suprised, perhaps even after it has started reading!) */
+ 	  sigsetmask (oldmask);
+ 
  	  /* You must give the tty away before you set the process group,
  	     and you must do these things only in the child.  Otherwise,
  	     race conditions can occur. */
***************
*** 671,676
  	last_asynchronous_pid = pid;
  
        last_made_pid = pid;
      }
  
    sigsetmask (oldmask);

--- 678,685 -----
  	last_asynchronous_pid = pid;
  
        last_made_pid = pid;
+ 
+       sigsetmask (oldmask);
      }
  
    return (pid);
***************
*** 673,679
        last_made_pid = pid;
      }
  
-   sigsetmask (oldmask);
    return (pid);
  }
  

--- 682,687 -----
        sigsetmask (oldmask);
      }
  
    return (pid);
  }
  
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads