summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-15 20:24:28 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2007-10-15 20:24:28 +0800
commit03b4958dd49fda257c130d3fd9f1b6bafc00e36d (patch)
tree91c3aff84b78253b644853248ad6f4a685ebc3aa
parent[BUILTIN] Use setvarint to set OPTIND (diff)
downloaddash-03b4958dd49fda257c130d3fd9f1b6bafc00e36d.tar.gz
dash-03b4958dd49fda257c130d3fd9f1b6bafc00e36d.zip
[EXEC] Fixed execing of scripts with no hash-bang
The function tryexec used the original name instead of the path found through
PATH search.  This patch fixes that.

Test case:

	trap 'rm -f $TMP' EXIT
	TMP=$(tempfile -s nosuchthing)

	cat <<- EOF > $TMP
		echo OK
	EOF
	chmod u+x $TMP

	cd /
	PATH=${TMP%/*} ${TMP##*/}

Old result:

	/bin/sh: Can't open filelgY4Fanosuchthing

New result:

	OK
-rw-r--r--ChangeLog4
-rw-r--r--src/eval.c3
-rw-r--r--src/exec.c21
3 files changed, 9 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 00c09c3..60bdfb5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2007-10-15  Herbert Xu <herbert@gondor.apana.org.au>
+
+	* Fixed execing of scripts with no hash-bang.
+
 2007-10-11  Herbert Xu <herbert@gondor.apana.org.au>
 
 	* Add assignment support in arithmetic expansions.
diff --git a/src/eval.c b/src/eval.c
index 2aa8317..1e0edd9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -727,7 +727,8 @@ evalcommand(union node *cmd, int flags)
 			argc++;
 	}
 
-	argv = nargv = stalloc(sizeof (char *) * (argc + 1));
+	/* Reserve one extra spot at the front for shellexec. */
+	argv = nargv = stalloc(sizeof (char *) * (argc + 2)) + 1;
 	for (sp = arglist.list ; sp ; sp = sp->next) {
 		TRACE(("evalcommand arg: %s\n", sp->text));
 		*nargv++ = sp->text;
diff --git a/src/exec.c b/src/exec.c
index 8a1f722..bbb70e8 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -149,11 +149,6 @@ shellexec(char **argv, const char *path, int idx)
 STATIC void
 tryexec(char *cmd, char **argv, char **envp)
 {
-	int repeated = 0;
-#if !defined(BSD) && !defined(linux)
-	char *p;
-#endif
-
 repeat:
 #ifdef SYSV
 	do {
@@ -162,19 +157,9 @@ repeat:
 #else
 	execve(cmd, argv, envp);
 #endif
-	if (repeated++) {
-		ckfree(argv);
-	} else if (errno == ENOEXEC) {
-		char **ap;
-		char **new;
-
-		for (ap = argv; *ap; ap++)
-			;
-		ap = new = ckmalloc((ap - argv + 2) * sizeof(char *));
-		*ap++ = cmd = _PATH_BSHELL;
-		while ((*ap++ = *argv++))
-			;
-		argv = new;
+	if (cmd != _PATH_BSHELL && errno == ENOEXEC) {
+		*argv-- = cmd;
+		*argv = cmd = _PATH_BSHELL;
 		goto repeat;
 	}
 }