aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2018-05-19 02:39:48 +0800
committerBen Hutchings <ben@decadent.org.uk>2020-03-28 21:42:55 +0000
commit6e48f19172d90268f524bf1a3788f7c023b24391 (patch)
treea41a86c9676c184db0c7c7c2c22a40ad6acdea86
parent1df4e2a6786b049decbc6ab1683108da86479891 (diff)
downloadklibc-6e48f19172d90268f524bf1a3788f7c023b24391.tar.gz
[klibc] dash: exec: Do not allocate stack string in padvance
[ dash commit 4f7527f8e49276894751a9b100e68bc46568bb85 ] Many callers of padvance immediately free the allocated string so this patch moves the stalloc call to the caller. Instead of returning the allocated string, padvance now returns the length to allocate (this may be longer than the actual string length, even including the NUL). For the case where we would previously return NULL, we now return -1. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--usr/dash/cd.c8
-rw-r--r--usr/dash/exec.c26
-rw-r--r--usr/dash/exec.h2
-rw-r--r--usr/dash/mail.c7
-rw-r--r--usr/dash/main.c12
5 files changed, 29 insertions, 26 deletions
diff --git a/usr/dash/cd.c b/usr/dash/cd.c
index a4e024d84e365..610a4fa889190 100644
--- a/usr/dash/cd.c
+++ b/usr/dash/cd.c
@@ -98,6 +98,7 @@ cdcmd(int argc, char **argv)
char c;
struct stat statb;
int flags;
+ int len;
flags = cdopt();
dest = *argptr;
@@ -127,9 +128,10 @@ dotdot:
if (!*dest)
dest = ".";
path = bltinlookup("CDPATH");
- while (path) {
- c = *path;
- p = padvance(&path, dest);
+ while (p = path, (len = padvance(&path, dest)) >= 0) {
+ c = *p;
+ p = stalloc(len);
+
if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
if (c && c != ':')
flags |= CD_PRINT;
diff --git a/usr/dash/exec.c b/usr/dash/exec.c
index c98f14c0b00c8..04ee2ba908e80 100644
--- a/usr/dash/exec.c
+++ b/usr/dash/exec.c
@@ -118,13 +118,13 @@ shellexec(char **argv, const char *path, int idx)
e = errno;
} else {
e = ENOENT;
- while ((cmdname = padvance(&path, argv[0])) != NULL) {
+ while (padvance(&path, argv[0]) >= 0) {
+ cmdname = stackblock();
if (--idx < 0 && pathopt == NULL) {
tryexec(cmdname, argv, envp);
if (errno != ENOENT && errno != ENOTDIR)
e = errno;
}
- stunalloc(cmdname);
}
}
@@ -182,8 +182,7 @@ repeat:
const char *pathopt;
-char *
-padvance(const char **path, const char *name)
+int padvance(const char **path, const char *name)
{
const char *p;
char *q;
@@ -191,7 +190,7 @@ padvance(const char **path, const char *name)
size_t len;
if (*path == NULL)
- return NULL;
+ return -1;
start = *path;
for (p = start ; *p && *p != ':' && *p != '%' ; p++);
len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
@@ -211,7 +210,7 @@ padvance(const char **path, const char *name)
*path = p + 1;
else
*path = NULL;
- return stalloc(len);
+ return len;
}
@@ -266,9 +265,9 @@ printentry(struct tblentry *cmdp)
idx = cmdp->param.index;
path = pathval();
do {
- name = padvance(&path, cmdp->cmdname);
- stunalloc(name);
+ padvance(&path, cmdp->cmdname);
} while (--idx >= 0);
+ name = stackblock();
out1str(name);
out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr);
}
@@ -291,6 +290,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
int e;
int updatetbl;
struct builtincmd *bcmd;
+ int len;
/* If name contains a slash, don't use PATH or hash table */
if (strchr(name, '/') != NULL) {
@@ -362,8 +362,8 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
e = ENOENT;
idx = -1;
loop:
- while ((fullname = padvance(&path, name)) != NULL) {
- stunalloc(fullname);
+ while ((len = padvance(&path, name)) >= 0) {
+ fullname = stackblock();
idx++;
if (pathopt) {
if (prefix(pathopt, "builtin")) {
@@ -398,7 +398,7 @@ loop:
if (!S_ISREG(statb.st_mode))
continue;
if (pathopt) { /* this is a %func directory */
- stalloc(strlen(fullname) + 1);
+ stalloc(len);
readcmdfile(fullname);
if ((cmdp = cmdlookup(name, 0)) == NULL ||
cmdp->cmdtype != CMDFUNCTION)
@@ -789,9 +789,9 @@ describe_command(out, command, path, verbose)
p = command;
} else {
do {
- p = padvance(&path, command);
- stunalloc(p);
+ padvance(&path, command);
} while (--j >= 0);
+ p = stackblock();
}
if (verbose) {
outfmt(
diff --git a/usr/dash/exec.h b/usr/dash/exec.h
index 9ccb305fef806..e241b74237b02 100644
--- a/usr/dash/exec.h
+++ b/usr/dash/exec.h
@@ -62,7 +62,7 @@ extern const char *pathopt; /* set by padvance */
void shellexec(char **, const char *, int)
__attribute__((__noreturn__));
-char *padvance(const char **, const char *);
+int padvance(const char **, const char *);
int hashcmd(int, char **);
void find_command(char *, struct cmdentry *, int, const char *);
struct builtincmd *find_builtin(const char *);
diff --git a/usr/dash/mail.c b/usr/dash/mail.c
index 02e07f777add1..7f9e49de5cc1f 100644
--- a/usr/dash/mail.c
+++ b/usr/dash/mail.c
@@ -77,9 +77,12 @@ chkmail(void)
setstackmark(&smark);
mpath = mpathset() ? mpathval() : mailval();
for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) {
- p = padvance(&mpath, nullstr);
- if (p == NULL)
+ int len;
+
+ len = padvance(&mpath, nullstr);
+ if (!len)
break;
+ p = stackblock();
if (*p == '\0')
continue;
for (q = p ; *q ; q++);
diff --git a/usr/dash/main.c b/usr/dash/main.c
index 8b3511891ce45..c87fbd73b2354 100644
--- a/usr/dash/main.c
+++ b/usr/dash/main.c
@@ -292,20 +292,18 @@ find_dot_file(char *basename)
char *fullname;
const char *path = pathval();
struct stat statb;
+ int len;
/* don't try this for absolute or relative paths */
if (strchr(basename, '/'))
return basename;
- while ((fullname = padvance(&path, basename)) != NULL) {
+ while ((len = padvance(&path, basename)) >= 0) {
+ fullname = stackblock();
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
- /*
- * Don't bother freeing here, since it will
- * be freed by the caller.
- */
- return fullname;
+ /* This will be freed by the caller. */
+ return stalloc(len);
}
- stunalloc(fullname);
}
/* not found in the PATH */