summary refs log tree commit diff
path: root/src/exec.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2018-05-19 02:39:52 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2018-05-28 17:12:23 +0800
commitcbb71a836874d176809a34e22f6b6e4e3ba8c85b (patch)
tree7bfba4c4202e600b13d660d74b6d93cb914a7733 /src/exec.c
parentexec: Never rehash regular built-ins (diff)
downloaddash-cbb71a836874d176809a34e22f6b6e4e3ba8c85b.tar.gz
dash-cbb71a836874d176809a34e22f6b6e4e3ba8c85b.zip
eval: Add assignment built-in support again
This patch adds assignment built-in support that used to exist
in dash prior to 0.3.8-15.  This is because it will soon be part
of POSIX, and the semantics are now much better defined.

Recognition is done at execution time, so even "command -- export"
or "var=export; command $var" should work.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to '')
-rw-r--r--src/exec.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/exec.c b/src/exec.c
index 6c0a64f..9d0215a 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -357,11 +357,8 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
 	}
 
 	updatetbl = (path == pathval());
-	if (!updatetbl) {
+	if (!updatetbl)
 		act |= DO_ALTPATH;
-		if (strstr(path, "%builtin") != NULL)
-			act |= DO_ALTBLTIN;
-	}
 
 	/* If name is in the table, check answer will be ok */
 	if ((cmdp = cmdlookup(name, 0)) != NULL) {
@@ -373,17 +370,20 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
 			abort();
 #endif
 		case CMDNORMAL:
-			bit = DO_ALTPATH;
+			bit = DO_ALTPATH | DO_REGBLTIN;
 			break;
 		case CMDFUNCTION:
 			bit = DO_NOFUNC;
 			break;
 		case CMDBUILTIN:
 			bit = cmdp->param.cmd->flags & BUILTIN_REGULAR ?
-			      0 : DO_ALTBLTIN;
+			      0 : DO_REGBLTIN;
 			break;
 		}
 		if (act & bit) {
+			if (act & bit & DO_REGBLTIN)
+				goto fail;
+
 			updatetbl = 0;
 			cmdp = NULL;
 		} else if (cmdp->rehash == 0)
@@ -393,11 +393,13 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
 
 	/* If %builtin not in path, check for builtin next */
 	bcmd = find_builtin(name);
-	if (bcmd && (bcmd->flags & BUILTIN_REGULAR || (
-		act & DO_ALTPATH ? !(act & DO_ALTBLTIN) : builtinloc <= 0
-	)))
+	if (bcmd && ((bcmd->flags & BUILTIN_REGULAR) | (act & DO_ALTPATH) |
+		     (builtinloc <= 0)))
 		goto builtin_success;
 
+	if (act & DO_REGBLTIN)
+		goto fail;
+
 	/* We have to search path. */
 	prev = -1;		/* where to start */
 	if (cmdp && cmdp->rehash) {	/* doing a rehash */
@@ -489,6 +491,7 @@ loop:
 		delete_cmd_entry();
 	if (act & DO_ERR)
 		sh_warnx("%s: %s", name, errmsg(e, E_EXEC));
+fail:
 	entry->cmdtype = CMDUNKNOWN;
 	return;