diff options
-rw-r--r-- | shell/ash.c | 74 |
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 | */ |
2570 | static const char *pathopt; /* set by path_advance */ | 2570 | static const char *pathopt; /* set by padvance */ |
2571 | 2571 | ||
2572 | static char * | 2572 | static int |
2573 | path_advance(const char **path, const char *name) | 2573 | padvance(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 | */ |
13343 | static char * | 13349 | static char * |
13344 | find_dot_file(char *name) | 13350 | find_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) */ |