Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 May 1998 11:57:00 +0200
From:      Martin Cracauer <cracauer@cons.org>
To:        Bruce Evans <bde@zeta.org.au>, cracauer@cons.org, freebsd-current@FreeBSD.ORG
Subject:   Re: make/SIGINT (Re: cvs commit: src/bin/sh jobs.c)
Message-ID:  <19980506115700.32044@cons.org>
In-Reply-To: <19980505122917.01946@cons.org>; from Martin Cracauer on Tue, May 05, 1998 at 12:29:17PM %2B0200
References:  <199804191143.VAA00099@godzilla.zeta.org.au> <19980422101203.65361@cons.org> <19980505122917.01946@cons.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--LZvS9be/3tNcYl/X
Content-Type: text/plain; charset=us-ascii

> The only test this sh version still fails on is that the wait builtin
> isn't interruptable by SIGINT.

The appended version makes the wait builtin interruptable, on the cost
of two new global variables. 

Martin
-- 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Martin Cracauer <cracauer@cons.org> http://www.cons.org/cracauer
  cracauer@wavehh.hanse.de (batched, preferred for large mails)
  Tel.: (private) +4940 5221829 Fax.: (private) +4940 5228536
  Paper: (private) Waldstrasse 200, 22846 Norderstedt, Germany

--LZvS9be/3tNcYl/X
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

? l
? builtins.c
? builtins.h
? mknodes
? nodes.h
? nodes.c
? mksyntax
? syntax.c
? syntax.h
? token.h
? sh
? y.tab.h
? arith.c
? arith_lex.c
? mkinit
? init.c
? sh.1.gz
? README
? .depend
Index: error.c
===================================================================
RCS file: /home/ftp/pub/FreeBSD/CVS-FreeBSD/src/bin/sh/error.c,v
retrieving revision 1.5.2.1
diff -c -r1.5.2.1 error.c
*** error.c	1997/08/25 09:09:38	1.5.2.1
--- error.c	1998/05/06 09:49:40
***************
*** 50,55 ****
--- 50,56 ----
  #include "output.h"
  #include "error.h"
  #include "show.h"
+ #include "trap.h"
  #include <signal.h>
  #include <unistd.h>
  #include <errno.h>
***************
*** 89,116 ****
   * Called from trap.c when a SIGINT is received.  (If the user specifies
   * that SIGINT is to be trapped or ignored using the trap builtin, then
   * this routine is not called.)  Suppressint is nonzero when interrupts
!  * are held using the INTOFF macro.  The call to _exit is necessary because
!  * there is a short period after a fork before the signal handlers are
!  * set to the appropriate value for the child.  (The test for iflag is
!  * just defensive programming.)
   */
  
  void
  onint() {
  	sigset_t sigset;
  
! 	if (suppressint) {
  		intpending++;
  		return;
  	}
  	intpending = 0;
  	sigemptyset(&sigset);
  	sigprocmask(SIG_SETMASK, &sigset, NULL);
! 	out2str("\n");
! 	if (rootshell && iflag)
  		exraise(EXINT);
! 	else
! 		_exit(128 + SIGINT);
  }
  
  
--- 90,124 ----
   * Called from trap.c when a SIGINT is received.  (If the user specifies
   * that SIGINT is to be trapped or ignored using the trap builtin, then
   * this routine is not called.)  Suppressint is nonzero when interrupts
!  * are held using the INTOFF macro.  If SIGINTs are not suppressed and
!  * the shell is not a root shell, then we want to be terminated if we
!  * get here, as if we were terminated directly by a SIGINT.  Arrange for
!  * this here.
   */
  
  void
  onint() {
  	sigset_t sigset;
  
! 	/* The !in_dotrap is save. The only way we can arrive here with
! 	 * in_dotrap set is that a trap handler set SIGINT to default
! 	 * and killed itself.
! 	 */
! 
! 	if (suppressint && !in_dotrap) {
  		intpending++;
  		return;
  	}
  	intpending = 0;
  	sigemptyset(&sigset);
  	sigprocmask(SIG_SETMASK, &sigset, NULL);
! 	write(STDERR_FILENO, "\n", 1);
! 	if (rootshell /* && iflag ?? */)
  		exraise(EXINT);
! 	else {
! 		signal(SIGINT, SIG_DFL);
! 		kill(getpid(), SIGINT);
! 	}
  }
  
  
Index: jobs.c
===================================================================
RCS file: /home/ftp/pub/FreeBSD/CVS-FreeBSD/src/bin/sh/jobs.c,v
retrieving revision 1.8.2.4
diff -c -r1.8.2.4 jobs.c
*** jobs.c	1998/02/15 11:32:25	1.8.2.4
--- jobs.c	1998/05/06 09:49:40
***************
*** 85,90 ****
--- 85,92 ----
  int initialpgrp;		/* pgrp of shell on invocation */
  int curjob;			/* current job */
  #endif
+ int in_waitcmd = 0;		/* Are we in waitcmd? */
+ volatile sig_atomic_t breakwaitcmd = 0;	/* Should wait be terminated? */
  
  #if JOBS
  STATIC void restartjob __P((struct job *));
***************
*** 383,389 ****
  	} else {
  		job = NULL;
  	}
! 	for (;;) {	/* loop until process terminated or stopped */
  		if (job != NULL) {
  			if (job->state) {
  				status = job->ps[job->nprocs - 1].status;
--- 385,394 ----
  	} else {
  		job = NULL;
  	}
! 	in_waitcmd++;
! 	do {	/* loop until process terminated or stopped or SIGINT is
! 		 * received 
! 		 */
  		if (job != NULL) {
  			if (job->state) {
  				status = job->ps[job->nprocs - 1].status;
***************
*** 408,415 ****
  					break;
  			}
  		}
! 		dowait(1, (struct job *)NULL);
! 	}
  }
  
  
--- 413,420 ----
  					break;
  			}
  		}
! 	} while (dowait(1, (struct job *)NULL) != -1);
! 	in_waitcmd--;
  }
  
  
***************
*** 725,733 ****
  		st = WTERMSIG(status) + 128;
  	if (! JOBS || jp->state == JOBDONE)
  		freejob(jp);
! 	CLEAR_PENDING_INT;
! 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
! 		kill(getpid(), SIGINT);
  	INTON;
  	return st;
  }
--- 730,741 ----
  		st = WTERMSIG(status) + 128;
  	if (! JOBS || jp->state == JOBDONE)
  		freejob(jp);
! 	if (int_pending()) {
! 		if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
! 			kill(getpid(), SIGINT);
! 		else
! 			CLEAR_PENDING_INT;
! 	}
  	INTON;
  	return st;
  }
***************
*** 757,763 ****
  	do {
  		pid = waitproc(block, &status);
  		TRACE(("wait returns %d, status=%d\n", pid, status));
! 	} while (pid == -1 && errno == EINTR);
  	if (pid <= 0)
  		return pid;
  	INTOFF;
--- 765,775 ----
  	do {
  		pid = waitproc(block, &status);
  		TRACE(("wait returns %d, status=%d\n", pid, status));
! 	} while (pid == -1 && errno == EINTR && breakwaitcmd == 0);
! 	if (breakwaitcmd != 0) {
! 		breakwaitcmd = 0;
! 		return -1;
! 	}
  	if (pid <= 0)
  		return pid;
  	INTOFF;
Index: jobs.h
===================================================================
RCS file: /home/ftp/pub/FreeBSD/CVS-FreeBSD/src/bin/sh/jobs.h,v
retrieving revision 1.3.2.1
diff -c -r1.3.2.1 jobs.h
*** jobs.h	1997/08/25 09:10:02	1.3.2.1
--- jobs.h	1998/05/06 09:49:40
***************
*** 42,47 ****
--- 42,48 ----
  #define FORK_BG 1
  #define FORK_NOJOB 2
  
+ #include <signal.h> /* For sig_atomic_t */
  
  /*
   * A job structure contains information about a job.  A job is either a
***************
*** 77,82 ****
--- 78,85 ----
  
  extern pid_t backgndpid;	/* pid of last background process */
  extern int job_warning;		/* user was warned about stopped jobs */
+ extern int in_waitcmd;		/* Are we in wait? */
+ extern volatile sig_atomic_t breakwaitcmd; /* Should wait be terminated? */
  
  void setjobctl __P((int));
  int fgcmd __P((int, char **));
Index: trap.c
===================================================================
RCS file: /home/ftp/pub/FreeBSD/CVS-FreeBSD/src/bin/sh/trap.c,v
retrieving revision 1.4.2.2
diff -c -r1.4.2.2 trap.c
*** trap.c	1998/02/15 11:32:27	1.4.2.2
--- trap.c	1998/05/06 09:49:40
***************
*** 73,79 ****
  
  
  MKINIT char sigmode[NSIG];	/* current value of signal */
! int pendingsigs;			/* indicates some signal received */
  static char *trap[NSIG];	/* trap handler commands */
  static char gotsig[NSIG];	/* indicates specified signal received */
  static int ignore_sigchld;	/* Used while handling SIGCHLD traps. */
--- 73,80 ----
  
  
  MKINIT char sigmode[NSIG];	/* current value of signal */
! int pendingsigs;		/* indicates some signal received */
! int in_dotrap = 0;		/* Do we execute in a trap handler? */
  static char *trap[NSIG];	/* trap handler commands */
  static char gotsig[NSIG];	/* indicates specified signal received */
  static int ignore_sigchld;	/* Used while handling SIGCHLD traps. */
***************
*** 219,229 ****
  		action = S_CATCH;
  	else
  		action = S_IGN;
! 	if (rootshell && action == S_DFL) {
  		switch (signo) {
  		case SIGINT:
! 			if (iflag)
! 				action = S_CATCH;
  			break;
  		case SIGQUIT:
  #ifdef DEBUG
--- 220,229 ----
  		action = S_CATCH;
  	else
  		action = S_IGN;
! 	if (action == S_DFL) {
  		switch (signo) {
  		case SIGINT:
! 			action = S_CATCH;
  			break;
  		case SIGQUIT:
  #ifdef DEBUG
***************
*** 234,248 ****
  				break;
  			}
  #endif
! 			/* FALLTHROUGH */
  		case SIGTERM:
! 			if (iflag)
  				action = S_IGN;
  			break;
  #if JOBS
  		case SIGTSTP:
  		case SIGTTOU:
! 			if (mflag)
  				action = S_IGN;
  			break;
  #endif
--- 234,249 ----
  				break;
  			}
  #endif
! 			action = S_IGN;
! 			break;
  		case SIGTERM:
! 			if (rootshell && iflag)
  				action = S_IGN;
  			break;
  #if JOBS
  		case SIGTSTP:
  		case SIGTTOU:
! 			if (rootshell && mflag)
  				action = S_IGN;
  			break;
  #endif
***************
*** 354,359 ****
--- 355,364 ----
  	if (signo != SIGCHLD || !ignore_sigchld)
  		gotsig[signo] = 1;
  	pendingsigs++;
+ 	if (signo == SIGINT && in_waitcmd != 0) {
+ 		dotrap();
+ 		breakwaitcmd = 1;
+ 	}
  }
  
  
***************
*** 367,372 ****
--- 372,378 ----
  	int i;
  	int savestatus;
  
+ 	in_dotrap++;
  	for (;;) {
  		for (i = 1; i < NSIG; i++) {
  			if (gotsig[i]) {
***************
*** 390,395 ****
--- 396,402 ----
  		if (i >= NSIG)
  			break;
  	}
+ 	in_dotrap--;
  	pendingsigs = 0;
  }
  
***************
*** 401,407 ****
  setinteractive(on)
  	int on;
  {
! 	static int is_interactive = 0;
  
  	if (on == is_interactive)
  		return;
--- 408,414 ----
  setinteractive(on)
  	int on;
  {
! 	static int is_interactive = -1;
  
  	if (on == is_interactive)
  		return;
Index: trap.h
===================================================================
RCS file: /home/ftp/pub/FreeBSD/CVS-FreeBSD/src/bin/sh/trap.h,v
retrieving revision 1.3.2.2
diff -c -r1.3.2.2 trap.h
*** trap.h	1998/02/15 11:32:27	1.3.2.2
--- trap.h	1998/05/06 09:49:40
***************
*** 38,43 ****
--- 38,44 ----
   */
  
  extern int pendingsigs;
+ extern int in_dotrap;
  
  int trapcmd __P((int, char **));
  void clear_traps __P((void));

--LZvS9be/3tNcYl/X--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



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