Subject: bin/18299: sh(1) race condition on SIGINT
To: None <gnats-bugs@gnats.netbsd.org>
From: None <elric@imrryr.org>
List: netbsd-bugs
Date: 09/15/2002 05:04:03
>Number:         18299
>Category:       bin
>Synopsis:       sh(1) race condition on SIGINT
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Sep 15 02:05:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Roland Dowdeswell
>Release:        NetBSD 1.6_BETA1
>Organization:
	not much at this time of the morning.
>Environment:
System: NetBSD arioch.imrryr.org 1.6_BETA1 NetBSD 1.6_BETA1 (ARIOCH) #0: Fri Jun 28 12:36:20 EDT 2002 elric@arioch.imrryr.org:/usr/src/sys/arch/alpha/compile/ARIOCH alpha
Architecture: alpha
Machine: alpha
>Description:
	Sometimes a SIGINT will cause the shell to be suspended on
	SIGTTIN.  I've had a quick gdb/ktrace/UTSL and I think that
	what's happening here is that in eval.c, evalcommand():

	line 740 forks, the parent jumps to 875.  The parent then
	waits for the child.  This wait is different than the wait
	in the main loop, though, because it will reassert control
	of the tty.

	The child goes off and does its thing, generally exec'ing.

	The problem occurs when the child exits before the parent
	gets to the wait and the user presses ^C before the parent
	gets to the wait.  In that case, it will longjmp(3) to the
	main loop which will collect the child w/o doing the right
	group mgmt and then try to read from stdin and be delivered
	a SIGTTIN.
>How-To-Repeat:
	You can reproduce it by:

		$ for i in $(jot 5000); do /bin/echo -n; done
		^C

	a lot.  Eventually, you'll get:

		$ for i in $(jot 5000); do /bin/echo -n; done
		^C
		[1] 26070 Exit 0              /bin/echo -n
		$ [1] + Stopped (tty input)  sh 

>Fix:
	none provided, yet.
>Release-Note:
>Audit-Trail:
>Unformatted: