Subject: bin/5359: reboot(8) should ignore SIGPIPE
To: None <gnats-bugs@gnats.netbsd.org>
From: None <nathanw@MIT.EDU>
List: netbsd-bugs
Date: 04/24/1998 16:42:40
>Number:         5359
>Category:       bin
>Synopsis:       reboot(8) can die from SIGPIPE at a bad time.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 24 13:50:00 1998
>Last-Modified:
>Originator:     Nathan J Williams
>Organization:
	Maassachvsetts Institvte of Technology
>Release:        NetBSD 1.3.1
>Environment:
System: NetBSD snorklewacker.mit.edu 1.3.1 NetBSD 1.3.1 (ATHENADEBUG) #1: Fri Apr 24 14:58:34 EDT 1998 nathanw@snorklewacker.mit.edu:/u1/var/tmp/sys/arch/i386/compile/ATHENADEBUG i386


>Description:
	The reboot program doesn't make any attempt to deal with SIGPIPE, 
so if it's run somewhere inside a pipeline (say, deep inside a system
update script whose output is being logged through tee) and it has a 
diagnostic to report (such as if not all the processes will die), it will
get SIGPIPE when it tries to write the diagnostic, and die without
actually rebooting the system. 
	By the time this happens most useful processes will be dead, so
the system will be stuck in a non-useful state. 
>How-To-Repeat:
	Get some process stuck in disk wait or something, and run "reboot | cat". Watch system hang. 
>Fix:

	This patch makes reboot ignore SIGPIPE, as there's really not much else
it can do with it. It might be a good idea to ignore SIGTSTP, SIGTTIN, SIGTTOU,
SIGTERM, and possibly others, as losing to a signal after killing most of
the system is not very useful. 

*** reboot.c.orig	Fri Apr 24 16:33:11 1998
--- reboot.c	Fri Apr 24 16:33:20 1998
***************
*** 160,165 ****
--- 160,168 ----
  
  	/* Ignore the SIGHUP we get when our parent shell dies. */
  	(void)signal(SIGHUP, SIG_IGN);
+ 	/* If we're running in a pipeline, we don't want to die
+ 	 * after killing whatever we're writing to. */
+ 	(void)signal(SIGPIPE, SIG_IGN);
  
  	/* Send a SIGTERM first, a chance to save the buffers. */
  	if (kill(-1, SIGTERM) == -1) {
>Audit-Trail:
>Unformatted: