aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 6505f4984..e89cecf0b 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2560,17 +2560,17 @@ listvars(int on, int off, struct strlist *lp, char ***end)
2560/* ============ Path search helper 2560/* ============ Path search helper
2561 * 2561 *
2562 * The variable path (passed by reference) should be set to the start 2562 * The variable path (passed by reference) should be set to the start
2563 * of the path before the first call; path_advance will update 2563 * of the path before the first call; padvance will update
2564 * this value as it proceeds. Successive calls to path_advance will return 2564 * this value as it proceeds. Successive calls to padvance will return
2565 * the possible path expansions in sequence. If an option (indicated by 2565 * the possible path expansions in sequence. If an option (indicated by
2566 * a percent sign) appears in the path entry then the global variable 2566 * a percent sign) appears in the path entry then the global variable
2567 * pathopt will be set to point to it; otherwise pathopt will be set to 2567 * pathopt will be set to point to it; otherwise pathopt will be set to
2568 * NULL. 2568 * NULL.
2569 */ 2569 */
2570static const char *pathopt; /* set by path_advance */ 2570static const char *pathopt; /* set by padvance */
2571 2571
2572static char * 2572static int
2573path_advance(const char **path, const char *name) 2573padvance(const char **path, const char *name)
2574{ 2574{
2575 const char *p; 2575 const char *p;
2576 char *q; 2576 char *q;
@@ -2578,7 +2578,7 @@ path_advance(const char **path, const char *name)
2578 size_t len; 2578 size_t len;
2579 2579
2580 if (*path == NULL) 2580 if (*path == NULL)
2581 return NULL; 2581 return -1;
2582 start = *path; 2582 start = *path;
2583 for (p = start; *p && *p != ':' && *p != '%'; p++) 2583 for (p = start; *p && *p != ':' && *p != '%'; p++)
2584 continue; 2584 continue;
@@ -2599,7 +2599,7 @@ path_advance(const char **path, const char *name)
2599 *path = p + 1; 2599 *path = p + 1;
2600 else 2600 else
2601 *path = NULL; 2601 *path = NULL;
2602 return stalloc(len); 2602 return len;
2603} 2603}
2604 2604
2605 2605
@@ -2840,6 +2840,7 @@ cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2840 char c; 2840 char c;
2841 struct stat statb; 2841 struct stat statb;
2842 int flags; 2842 int flags;
2843 int len;
2843 2844
2844 flags = cdopt(); 2845 flags = cdopt();
2845 dest = *argptr; 2846 dest = *argptr;
@@ -2869,9 +2870,10 @@ cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2869 if (!*dest) 2870 if (!*dest)
2870 dest = "."; 2871 dest = ".";
2871 path = bltinlookup("CDPATH"); 2872 path = bltinlookup("CDPATH");
2872 while (path) { 2873 while (p = path, (len = padvance(&path, dest)) >= 0) {
2873 c = *path; 2874 c = *p;
2874 p = path_advance(&path, dest); 2875 p = stalloc(len);
2876
2875 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { 2877 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2876 if (c && c != ':') 2878 if (c && c != ':')
2877 flags |= CD_PRINT; 2879 flags |= CD_PRINT;
@@ -8169,13 +8171,13 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
8169 } else { 8171 } else {
8170 try_PATH: 8172 try_PATH:
8171 e = ENOENT; 8173 e = ENOENT;
8172 while ((cmdname = path_advance(&path, prog)) != NULL) { 8174 while (padvance(&path, argv[0]) >= 0) {
8175 cmdname = stackblock();
8173 if (--idx < 0 && pathopt == NULL) { 8176 if (--idx < 0 && pathopt == NULL) {
8174 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); 8177 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
8175 if (errno != ENOENT && errno != ENOTDIR) 8178 if (errno != ENOENT && errno != ENOTDIR)
8176 e = errno; 8179 e = errno;
8177 } 8180 }
8178 stunalloc(cmdname);
8179 } 8181 }
8180 } 8182 }
8181 8183
@@ -8208,9 +8210,9 @@ printentry(struct tblentry *cmdp)
8208 idx = cmdp->param.index; 8210 idx = cmdp->param.index;
8209 path = pathval(); 8211 path = pathval();
8210 do { 8212 do {
8211 name = path_advance(&path, cmdp->cmdname); 8213 padvance(&path, cmdp->cmdname);
8212 stunalloc(name);
8213 } while (--idx >= 0); 8214 } while (--idx >= 0);
8215 name = stackblock();
8214 out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr)); 8216 out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
8215} 8217}
8216 8218
@@ -8603,9 +8605,9 @@ describe_command(char *command, const char *path, int describe_command_verbose)
8603 p = command; 8605 p = command;
8604 } else { 8606 } else {
8605 do { 8607 do {
8606 p = path_advance(&path, command); 8608 padvance(&path, command);
8607 stunalloc(p);
8608 } while (--j >= 0); 8609 } while (--j >= 0);
8610 p = stackblock();
8609 } 8611 }
8610 if (describe_command_verbose) { 8612 if (describe_command_verbose) {
8611 out1fmt(" is %s", p); 8613 out1fmt(" is %s", p);
@@ -11020,8 +11022,12 @@ chkmail(void)
11020 mpath = mpathset() ? mpathval() : mailval(); 11022 mpath = mpathset() ? mpathval() : mailval();
11021 new_hash = 0; 11023 new_hash = 0;
11022 for (;;) { 11024 for (;;) {
11023 p = path_advance(&mpath, nullstr); 11025 int len;
11024 if (p == NULL) 11026
11027 len = padvance(&mpath, nullstr);
11028 if (!len)
11029 break;
11030 p = stackblock();
11025 break; 11031 break;
11026 if (*p == '\0') 11032 if (*p == '\0')
11027 continue; 11033 continue;
@@ -13341,33 +13347,30 @@ cmdloop(int top)
13341 * search for the file, which is necessary to find sub-commands. 13347 * search for the file, which is necessary to find sub-commands.
13342 */ 13348 */
13343static char * 13349static char *
13344find_dot_file(char *name) 13350find_dot_file(char *basename)
13345{ 13351{
13346 char *fullname; 13352 char *fullname;
13347 const char *path = pathval(); 13353 const char *path = pathval();
13348 struct stat statb; 13354 struct stat statb;
13355 int len;
13349 13356
13350 /* don't try this for absolute or relative paths */ 13357 /* don't try this for absolute or relative paths */
13351 if (strchr(name, '/')) 13358 if (strchr(basename, '/'))
13352 return name; 13359 return basename;
13353 13360
13354 while ((fullname = path_advance(&path, name)) != NULL) { 13361 while ((len = padvance(&path, basename)) >= 0) {
13362 fullname = stackblock();
13355 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { 13363 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
13356 /* 13364 /* This will be freed by the caller. */
13357 * Don't bother freeing here, since it will 13365 return stalloc(len);
13358 * be freed by the caller.
13359 */
13360 return fullname;
13361 } 13366 }
13362 if (fullname != name)
13363 stunalloc(fullname);
13364 } 13367 }
13365 /* not found in PATH */ 13368 /* not found in PATH */
13366 13369
13367#if ENABLE_ASH_BASH_SOURCE_CURDIR 13370#if ENABLE_ASH_BASH_SOURCE_CURDIR
13368 return name; 13371 return basename;
13369#else 13372#else
13370 ash_msg_and_raise_error("%s: not found", name); 13373 ash_msg_and_raise_error("%s: not found", basename);
13371 /* NOTREACHED */ 13374 /* NOTREACHED */
13372#endif 13375#endif
13373} 13376}
@@ -13470,6 +13473,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
13470 int e; 13473 int e;
13471 int updatetbl; 13474 int updatetbl;
13472 struct builtincmd *bcmd; 13475 struct builtincmd *bcmd;
13476 int len;
13473 13477
13474 /* If name contains a slash, don't use PATH or hash table */ 13478 /* If name contains a slash, don't use PATH or hash table */
13475 if (strchr(name, '/') != NULL) { 13479 if (strchr(name, '/') != NULL) {
@@ -13561,10 +13565,8 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
13561 e = ENOENT; 13565 e = ENOENT;
13562 idx = -1; 13566 idx = -1;
13563 loop: 13567 loop:
13564 while ((fullname = path_advance(&path, name)) != NULL) { 13568 while ((len = padvance(&path, name)) >= 0) {
13565 stunalloc(fullname); 13569 fullname = stackblock();
13566 /* NB: code below will still use fullname
13567 * despite it being "unallocated" */
13568 idx++; 13570 idx++;
13569 if (pathopt) { 13571 if (pathopt) {
13570 if (prefix(pathopt, "builtin")) { 13572 if (prefix(pathopt, "builtin")) {
@@ -13598,7 +13600,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
13598 if (!S_ISREG(statb.st_mode)) 13600 if (!S_ISREG(statb.st_mode))
13599 continue; 13601 continue;
13600 if (pathopt) { /* this is a %func directory */ 13602 if (pathopt) { /* this is a %func directory */
13601 stalloc(strlen(fullname) + 1); 13603 stalloc(len);
13602 /* NB: stalloc will return space pointed by fullname 13604 /* NB: stalloc will return space pointed by fullname
13603 * (because we don't have any intervening allocations 13605 * (because we don't have any intervening allocations
13604 * between stunalloc above and this stalloc) */ 13606 * between stunalloc above and this stalloc) */