[comp.os.minix] Patch for 1.5 /bin/sh

paradis@acestes.UUCP (Jim Paradis) (03/26/91)

While I'm on the subject of shells, I figured I'd share with you a fix for
an obscure bug in good ole /bin/sh... I discovered this bug when I was
trying to run the config script for C news sometime back.

The nature of the bug is that if you include a "grave command" as part
of a builtin command, then the process that gets spawned off to execute
the grave command doesn't have its status collected until the next
external command is run -- it remains a zombie.  An example of this
sort of thing would be if you had a line of the form "var=`command`".

If you have enough of these lines in a row with no intervening external
command, then eventually you fill up the process table with zombies,
and you bomb out with a "no more processes" error (and adding debug
code to the shell script to try and isolate the problem often makes
it go away 8-) 8-( )

Anyhow, here are the patches for this one... the fix is just to ensure
that status is collected from a grave command as soon as it's run.

------------------------cut here--------------------------------------
*** sh.h.orig	Mon Nov  5 08:29:20 1990
--- sh.h	Mon Nov  5 08:29:05 1990
***************
*** 265,270 ****
--- 265,271 ----
  	char	nlcount;	/* for `'s */
  	char	xchar;		/* for `'s */
  	char	task;		/* reason for pushed IO */
+ 	int	pid;		/* Process ID of subproc (for `'s) */
  };
  Extern	struct	io	iostack[NPUSH];
  #define	XOTHER	0	/* none of the below */
*** sh4.c.orig	Mon Nov  5 08:29:45 1990
--- sh4.c	Mon Nov  5 08:29:08 1990
***************
*** 357,362 ****
--- 357,364 ----
  		e.iop->argp->aword = ++cp;
  		close(pf[1]);
  		PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar);
+ 		/* Save the PID so we can gather its status when done */
+ 		e.iop->pid = i;
  		return(1);
  	}
  	*cp = 0;
*** sh5.c.orig	Mon Nov  5 08:30:10 1990
--- sh5.c	Mon Nov  5 08:29:11 1990
***************
*** 84,89 ****
--- 84,95 ----
  					ioecho('\n');
  			        return '\n';
  		        }
+ 		        else if (c == 0 && e.iop->task == XGRAVE) {
+ 			    /* Gravechar returned EOF; now wait for
+ 			     * the subprocess to exit.
+ 			     */
+ 			    waitfor(e.iop->pid, 0);
+ 			}
  		    }
  		    if (e.iop->task == XIO) {
  			if (multiline)
-- 
Jim Paradis                  UUCP:  harvard!m2c!jjmhome!acestes!paradis
9 Carlstad St.               AT&T:  (508) 792-3810
Worcester, MA 01607-1569     ICBM:  42deg 13' 52",  71deg 47' 51"