Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Feb 1998 09:34:39 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        cracauer@cons.org, cvs-commiters@FreeBSD.ORG
Subject:   Re: Please review fix for /bin/sh SIGQUIT/SIGINT problem
Message-ID:  <199802052234.JAA25791@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>This diff fixes interactive shells in the case of background jobs. Any
>more special case?

I don't think this is right.  sh already has lots of signal handling,
and general uses INTOFF/INTON to optimize it.  This seems to work right
in interactive mode.  You would probably need to duplicate lots more of
the INTOFF/INTON bracketing to get the signal handling right.  E.g.,
signals need to be restored after fork() failure to match the INTON
there.

sh doesn't catch any signals at all in non-interactive mode (at least
for `sh -c testprog').  The following makes it handle SIGINT in
non-interactive mode much like in interactive mode (but probably not
quite right for non-i mode).  SIGTERM is still handled differently.

---
diff -c2 trap.c~ trap.c
*** trap.c~	Tue Nov 11 18:15:35 1997
--- trap.c	Fri Feb  6 08:38:25 1998
***************
*** 223,227 ****
--- 223,229 ----
  		switch (signo) {
  		case SIGINT:
+ #if 0 /* XXX */
  			if (iflag)
+ #endif
  				action = S_CATCH;
  			break;
***************
*** 402,406 ****
  	int on;
  {
! 	static int is_interactive = 0;
  
  	if (on == is_interactive)
--- 404,408 ----
  	int on;
  {
! 	static int is_interactive = -1;
  
  	if (on == is_interactive)
---

I'm not sure if INTOFF/INTON actually works in interactive mode.  There
is lots of code like:

	evalsubshell:
		forkshell();	/* does INTOFF/INTON internally */
		INTOFF;
		waitforjob();	/* does INTOFF/INTON internally (no-op here) */
		INTON;

I would have expected it to do the INTOFF before forkshell() so that
there is no window for an interrupt between the fork and the wait.

Your fix makes the nesting of the signal handling hard to follow and
not obviously correct.  forkshell() leaves signals "off" and depends
on waitforjob() to turn them "on" again by restoring the signal state.
There are other calls to waitforjob()...

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802052234.JAA25791>