@@ -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;
@@ -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(
@@ -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 *);
@@ -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++);
@@ -290,20 +290,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 */
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>