dslinux/user/busybox/shell msh.c

stsp stsp at user.in-berlin.de
Sun Oct 1 13:27:16 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/busybox/shell
In directory antilope:/tmp/cvs-serv6302

Modified Files:
	msh.c 
Log Message:
Make msh detect exit status for commands run in graves (i.e. `command`).

Patch submitted by John S. Skogtvedt.

Extracts from John's submit email:

  Test case:
  dlginput=`dialog --stdout --inputbox Foo 0 0`
  echo $?
  
  Should echo 0 if OK was selected, 1 if Cancel was selected or 255 if the
  escape key was pressed. In msh it always echoes 0.
  
  I have to admit I don't fully understand how msh works, and there may be
  a better way of solving it.
  
  Here's what I know:
  
  When the shell encounters `...` grave() is run.
  Currently it doesn't capture the exit status.
  
  After each command ("ls", "var=foo", etc) forkexec() sets $? to 0
  unless a external command was run, in which case $? is set to the exit
  status of the command.

  What the patch does:
  
  Captures the exit status in grave() and assigns it to a global variable
  grave_exitstatus.
  Checks for grave_exitstatus != -1 in forkexec(), and if so sets $? to
  the exit status and sets grave_exitstatus to -1.



Index: msh.c
===================================================================
RCS file: /cvsroot/dslinux/dslinux/user/busybox/shell/msh.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- msh.c	11 Aug 2006 16:03:09 -0000	1.4
+++ msh.c	1 Oct 2006 11:27:13 -0000	1.5
@@ -750,6 +750,7 @@
 static int iounit = IODEFAULT;
 static YYSTYPE yylval;
 static char *elinep = line + sizeof(line) - 5;
+static int grave_exitstatus = -1; /* exitstatus of command run by grave() */
 
 static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 };	/* temporary for PUSHIO */
 static struct ioarg ioargstack[NPUSH];
@@ -2914,7 +2915,13 @@
 		if (cp == NULL && t->ioact == NULL) {
 			while ((cp = *owp++) != NULL && assign(cp, COPYV));
 			DBGPRINTF(("FORKEXEC: returning setstatus()\n"));
-			return (setstatus(0));
+			if (grave_exitstatus != -1) {
+				i = grave_exitstatus;
+				grave_exitstatus = -1;
+				return (setstatus(i));
+			} else {
+				return (setstatus(0));
+			}
 		} else if (cp != NULL) {
 			shcom = inbuilt(cp);
 		}
@@ -4402,7 +4409,11 @@
 		return (0);
 	}
 	if (i != 0) {
-		waitpid(i, NULL, 0);
+		waitpid(i, &grave_exitstatus, 0);
+		if WIFEXITED(grave_exitstatus)
+			grave_exitstatus = WEXITSTATUS(grave_exitstatus);
+		else
+			grave_exitstatus = 0;
 		e.iop->argp->aword = ++cp;
 		close(pf[1]);
 		PUSHIO(afile, remap(pf[0]),




More information about the dslinux-commit mailing list