[BusyBox-cvs] busybox/shell msh.c,1.11,1.12

Erik Andersen andersen at codepoet.org
Fri Mar 14 16:06:03 UTC 2003


Update of /var/cvs/busybox/shell
In directory winder:/tmp/cvs-serv2557

Modified Files:
	msh.c 
Log Message:
Patch from Jonas Holmberg, adjusted by Robert Schwebel, and
later re-adjusted by me to fix msh backtick handling


Index: msh.c
===================================================================
RCS file: /var/cvs/busybox/shell/msh.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- msh.c	11 Dec 2002 07:42:46 -0000	1.11
+++ msh.c	14 Mar 2003 16:05:59 -0000	1.12
@@ -5,6 +5,11 @@
  * This version of the Minix shell was adapted for use in busybox
  * by Erik Andersen <andersee at debian.org>
  *
+ * - backtick expansion did not work properly
+ *   Jonas Holmberg <jonas.holmberg at axis.com>
+ *   Robert Schwebel <r.schwebel at pengutronix.de>
+ *   Erik Andersen <andersee at debian.org>
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -222,7 +227,7 @@
 static char *strsave (char *s, int a );
 static char *evalstr (char *cp, int f );
 static char *putn (int n );
-static char *itoa (unsigned u, int n );
+static char *itoa (int n );
 static char *unquote (char *as );
 static struct var *lookup (char *n );
 static int rlookup (char *n );
@@ -664,7 +669,6 @@
 static struct env e ={line, iostack, iostack-1, (xint *)NULL, FDBASE, (struct env *)NULL};
 static void (*qflag)(int) = SIG_IGN;
 static char	shellname[] = "/bin/sh";
-static char	search[] = ":/bin:/usr/bin";
 static	int	startl;
 static	int	peeksym;
 static	int	nlseen;
@@ -687,7 +691,6 @@
 static char * current_prompt;
 #endif
 
-
 /* -------- sh.c -------- */
 /*
  * shell
@@ -722,11 +725,15 @@
 		setval(homedir, "/");
 	export(homedir);
 
-	setval(lookup("$"), itoa(getpid(), 5));
+	setval(lookup("$"), putn(getpid()));
 
 	path = lookup("PATH");
-	if (path->value == null)
-		setval(path, search);
+	if (path->value == null) {
+		if (geteuid() == 0)
+			setval(path, "/sbin:/bin:/usr/sbin:/usr/bin");
+		else
+			setval(path, "/bin:/usr/bin");
+	}
 	export(path);
 
 	ifs = lookup("IFS");
@@ -858,7 +865,7 @@
 
 	cp = m;
 	for (c='a'; c<='z'; c++)
-		if (flag[c])
+		if (flag[(int)c])
 			*cp++ = c;
 	*cp = 0;
 	setval(lookup("-"), m);
@@ -1047,32 +1054,16 @@
 putn(n)
 register int n;
 {
-	return(itoa(n, -1));
+	return(itoa(n));
 }
 
 static char *
-itoa(u, n)
-register unsigned u;
-int n;
+itoa(n)
+register int n;
 {
-	register char *cp;
 	static char s[20];
-	int m;
-
-	m = 0;
-	if (n < 0 && (int) u < 0) {
-		m++;
-		u = -u;
-	}
-	cp = s+sizeof(s);
-	*--cp = 0;
-	do {
-		*--cp = u%10 + '0';
-		u /= 10;
-	} while (--n > 0 || u);
-	if (m)
-		*--cp = '-';
-	return(cp);
+	snprintf(s, sizeof(s), "%u", n);
+	return(s);
 }
 
 static void
@@ -2326,6 +2317,9 @@
 
 	switch(t->type) {
 	case TPAREN:
+		rv = execute(t->left, pin, pout, 0);
+		break;
+			
 	case TCOM:
 		{
 			int child;
@@ -2877,12 +2871,12 @@
 			*v = e.linep;
 			tp = *--v;
 			*v = e.linep;
-			execve("/bin/sh", v, envp);
+			execve(shellname, v, envp);
 			*v = tp;
 			return("no Shell");
 
 		case ENOMEM:
-			return("program too big");
+			return((char*)memory_exhausted);
 
 		case E2BIG:
 			return("argument list too long");
@@ -3643,7 +3637,7 @@
  */
 static int
 subgetc(ec, quoted)
-register int ec;
+register char ec;
 int quoted;
 {
 	register char c;
@@ -3770,59 +3764,154 @@
 /*
  * Run the command in `...` and read its output.
  */
+
 static int
 grave(quoted)
 int quoted;
 {
-	register int i;
 	char *cp;
+	register int i;
+	int j;
 	int pf[2];
+	static char child_cmd[LINELIM];
+	char *src;
+	char *dest;
+	int count;
+	int ignore;
+	int ignore_once;
+	char *argument_list[4];
 
 #if __GNUC__
 	/* Avoid longjmp clobbering */
 	(void) &cp;
 #endif
+	
 	for (cp = e.iop->argp->aword; *cp != '`'; cp++)
 		if (*cp == 0) {
 			err("no closing `");
 			return(0);
 		}
+
+	/* string copy with dollar expansion */
+	src = e.iop->argp->aword;
+	dest = child_cmd;
+	count = 0;
+	ignore = 0;
+	ignore_once = 0;
+	while ((*src != '`') && (count < LINELIM)) {
+		if (*src == '\'')
+			ignore = !ignore;
+		if (*src == '\\')
+			ignore_once = 1;
+		if (*src == '$' && !ignore && !ignore_once) {
+			struct var *vp;
+			char var_name[LINELIM];
+			char alt_value[LINELIM];
+			int var_index = 0;
+			int alt_index = 0;
+			char operator = 0;
+			int braces = 0;
+			char *value;
+
+			src++;
+			if (*src == '{') {
+				braces = 1;
+				src++;
+			}
+
+			var_name[var_index++] = *src++;
+			while (isalnum(*src))
+				var_name[var_index++] = *src++;
+			var_name[var_index] = 0;
+
+			if (braces) {
+				switch (*src) {
+				case '}':
+					break;
+				case '-':
+				case '=':
+				case '+':
+				case '?':
+					operator = *src;
+					break;
+				default:
+					err("unclosed ${\n");
+					return(0);
+				}
+				if (operator) {	
+					src++;
+					while (*src && (*src != '}')) {
+						alt_value[alt_index++] = *src++;
+					}
+					alt_value[alt_index] = 0;
+					if (*src != '}') {
+						err("unclosed ${\n");
+						return(0);
+					}
+				}
+				src++;
+			}
+
+			vp = lookup(var_name);
+			if (vp->value != null)
+				value = (operator == '+')? alt_value : vp->value;
+			else if (operator == '?') {
+				err(alt_value);
+				return(0);
+			} else if (alt_index && (operator != '+')) {
+				value = alt_value;
+				if (operator == '=')
+					setval(vp, value);
+			} else
+				continue;
+
+			while (*value && (count < LINELIM)) {
+				*dest++ = *value++;
+				count++;
+			}
+		} else {
+			*dest++ = *src++;
+			count++;
+			ignore_once = 0;
+		}
+	}
+	*dest = '\0';
+	
 	if (openpipe(pf) < 0)
 		return(0);
-	if ((i = vfork()) == -1) {
+	while ((i = vfork()) == -1 && errno == EAGAIN)
+		;
+	if (i < 0) {
 		closepipe(pf);
-		err("try again");
+		err((char*)memory_exhausted);
 		return(0);
 	}
 	if (i != 0) {
+		waitpid(i, NULL, 0);
 		e.iop->argp->aword = ++cp;
 		close(pf[1]);
 		PUSHIO(afile, remap(pf[0]), (int(*)(struct ioarg *))((quoted)? qgravechar: gravechar));
 		return(1);
 	}
-	*cp = 0;
 	/* allow trapped signals */
-	for (i=0; i<=_NSIG; i++)
-		if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN)
-			signal(i, SIG_DFL);
+	/* XXX - Maybe this signal stuff should go as well? */
+	for (j=0; j<=_NSIG; j++)
+		if (ourtrap[j] && signal(j, SIG_IGN) != SIG_IGN)
+			signal(j, SIG_DFL);
+	
 	dup2(pf[1], 1);
 	closepipe(pf);
-	flag['e'] = 0;
-	flag['v'] = 0;
-	flag['n'] = 0;
-	cp = strsave(e.iop->argp->aword, 0);
-	areanum = 1;
-	freehere(areanum);
-	freearea(areanum);	/* free old space */
-	e.oenv = NULL;
-	e.iop = (e.iobase = iostack) - 1;
-	unquote(cp);
-	interactive = 0;
-	PUSHIO(aword, cp, nlchar);
-	onecommand();
-	exit(1);
+
+	argument_list[0] = shellname;
+	argument_list[1] = "-c";
+	argument_list[2] = child_cmd;
+	argument_list[3] = 0;
+
+	prs(rexecve(argument_list[0], argument_list, makenv()));
+	_exit(1);
 }
 
+
 static char *
 unquote(as)
 register char *as;
@@ -4194,7 +4283,7 @@
 		return(c);
 	}
 	c = readc();
- 	if (ec != '\'' && e.iop->task != XGRAVE) {
+	if ((ec != '\'') && (ec != '`') && (e.iop->task != XGRAVE)) {
 		if(c == '\\') {
 			c = readc();
 			if (c == '\n' && ec != '\"')
@@ -4457,7 +4546,7 @@
 	}
 
 #ifdef CONFIG_FEATURE_COMMAND_EDITING
-	if (interactive) {
+	if (interactive && isatty(ap->afile)) {
 	    static char mycommand[BUFSIZ];
 	    static int position = 0, size = 0;
 
@@ -4568,7 +4657,7 @@
 prn(u)
 unsigned u;
 {
-	prs(itoa(u, 0));
+	prs(itoa(u));
 }
 
 static void




More information about the busybox-cvs mailing list