From patchwork Tue May 15 06:37:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10400059 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 636F9600F4 for ; Tue, 15 May 2018 06:37:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3598D28672 for ; Tue, 15 May 2018 06:37:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2A35728673; Tue, 15 May 2018 06:37:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 79FB528675 for ; Tue, 15 May 2018 06:37:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752423AbeEOGhZ (ORCPT ); Tue, 15 May 2018 02:37:25 -0400 Received: from orcrist.hmeau.com ([104.223.48.154]:45648 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752334AbeEOGhY (ORCPT ); Tue, 15 May 2018 02:37:24 -0400 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1fITaM-0005XO-RW for ; Tue, 15 May 2018 14:37:22 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1fITaM-0000W4-1i; Tue, 15 May 2018 14:37:22 +0800 Subject: [v2 PATCH 12/12] exec: Do not allocate stack string in padvance References: <20180515063602.u6jdebjzcr6ve2dh@gondor.apana.org.au> To: DASH Mailing List Message-Id: From: Herbert Xu Date: Tue, 15 May 2018 14:37:22 +0800 Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- src/cd.c | 8 +++++--- src/exec.c | 26 +++++++++++++------------- src/exec.h | 2 +- src/mail.c | 7 +++++-- src/main.c | 12 +++++------- 5 files changed, 29 insertions(+), 26 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/src/cd.c b/src/cd.c index a4e024d..610a4fa 100644 --- a/src/cd.c +++ b/src/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/src/exec.c b/src/exec.c index c98f14c..04ee2ba 100644 --- a/src/exec.c +++ b/src/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/src/exec.h b/src/exec.h index 5317451..f0c5a28 100644 --- a/src/exec.h +++ b/src/exec.h @@ -64,7 +64,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/src/mail.c b/src/mail.c index 02e07f7..7f9e49d 100644 --- a/src/mail.c +++ b/src/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/src/main.c b/src/main.c index 8b35118..c87fbd7 100644 --- a/src/main.c +++ b/src/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 */