From 869fba0814b0c9256de536714f8ccbcf0369b391 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 4 Nov 2020 10:08:13 +0100 Subject: [PATCH] Make expand_path return allocated memory Gets rid of one PATH_MAX use. --- builtin/command.c | 9 ++++++--- builtin/dot.c | 3 ++- builtin/exec.c | 2 +- builtin/hash.c | 4 +++- builtin/type.c | 5 +++-- include/shell/path.h | 2 +- shell/path.c | 18 ++++++++++-------- shell/task/simple_command.c | 4 +++- 8 files changed, 29 insertions(+), 18 deletions(-) diff --git a/builtin/command.c b/builtin/command.c index fc9a7b5..cb4d56d 100644 --- a/builtin/command.c +++ b/builtin/command.c @@ -47,9 +47,10 @@ static int verify_command(struct mrsh_state *state, const char *command_name, } } - const char *expanded = expand_path(state, command_name, true, default_path); + char *expanded = expand_path(state, command_name, true, default_path); if (expanded != NULL) { printf("%s\n", expanded); + free(expanded); return 0; } @@ -62,8 +63,8 @@ static int run_command(struct mrsh_state *state, int argc, char *argv[], return mrsh_run_builtin(state, argc - _mrsh_optind, &argv[_mrsh_optind]); } - const char *path = expand_path(state, argv[0], true, default_path); - if (!path) { + char *path = expand_path(state, argv[0], true, default_path); + if (path == NULL) { fprintf(stderr, "%s: not found\n", argv[0]); return 127; } @@ -81,6 +82,8 @@ static int run_command(struct mrsh_state *state, int argc, char *argv[], exit(126); } + free(path); + struct mrsh_process *proc = process_create(state, pid); return job_wait_process(proc); } diff --git a/builtin/dot.c b/builtin/dot.c index 876f5d4..b6307d9 100644 --- a/builtin/dot.c +++ b/builtin/dot.c @@ -19,7 +19,7 @@ int builtin_dot(struct mrsh_state *state, int argc, char *argv[]) { return 1; } - const char *path = expand_path(state, argv[1], false, false); + char *path = expand_path(state, argv[1], false, false); if (!path) { fprintf(stderr, "%s: not found\n", argv[1]); if (!state->interactive) { @@ -34,6 +34,7 @@ int builtin_dot(struct mrsh_state *state, int argc, char *argv[]) { argv[1], strerror(errno)); goto error; } + free(path); struct mrsh_parser *parser = mrsh_parser_with_fd(fd); struct mrsh_program *program = mrsh_parse_program(parser); diff --git a/builtin/exec.c b/builtin/exec.c index 76f1ff1..f987730 100644 --- a/builtin/exec.c +++ b/builtin/exec.c @@ -17,7 +17,7 @@ int builtin_exec(struct mrsh_state *state, int argc, char *argv[]) { return 0; } - const char *path = expand_path(state, argv[_mrsh_optind], false, false); + char *path = expand_path(state, argv[_mrsh_optind], false, false); if (path == NULL) { fprintf(stderr, "exec: %s: command not found\n", argv[_mrsh_optind]); return 127; diff --git a/builtin/hash.c b/builtin/hash.c index 4aa849b..dba34f9 100644 --- a/builtin/hash.c +++ b/builtin/hash.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "builtin.h" #include "mrsh_getopt.h" @@ -41,11 +42,12 @@ int builtin_hash(struct mrsh_state *state, int argc, char *argv[]) { continue; } - const char *path = expand_path(state, utility, true, false); + char *path = expand_path(state, utility, true, false); if (path == NULL) { fprintf(stderr, "hash: command not found: %s\n", utility); return 1; } + free(path); } return 0; diff --git a/builtin/type.c b/builtin/type.c index 46954f5..a0b3b69 100644 --- a/builtin/type.c +++ b/builtin/type.c @@ -42,9 +42,10 @@ int builtin_type(struct mrsh_state *state, int argc, char *argv[]) { continue; } - const char *path = expand_path(state, name, true, false); - if (path) { + char *path = expand_path(state, name, true, false); + if (path != NULL) { fprintf(stdout, "%s is %s\n", name, path); + free(path); continue; } diff --git a/include/shell/path.h b/include/shell/path.h index dd54e41..932563b 100644 --- a/include/shell/path.h +++ b/include/shell/path.h @@ -10,7 +10,7 @@ * used instead of the $PATH variable. Fully qualified paths are returned * as-is. */ -const char *expand_path(struct mrsh_state *state, const char *file, bool exec, +char *expand_path(struct mrsh_state *state, const char *file, bool exec, bool default_path); #endif diff --git a/shell/path.c b/shell/path.c index ab6e546..f361211 100644 --- a/shell/path.c +++ b/shell/path.c @@ -8,10 +8,10 @@ #include "shell/path.h" #include "mrsh_limit.h" -const char *expand_path(struct mrsh_state *state, const char *file, bool exec, +char *expand_path(struct mrsh_state *state, const char *file, bool exec, bool default_path) { if (strchr(file, '/')) { - return file; + return strdup(file); } char *pathe; @@ -39,19 +39,20 @@ const char *expand_path(struct mrsh_state *state, const char *file, bool exec, } } - static char path[PATH_MAX + 1]; + char *path = NULL; char *basedir = strtok(pathe, ":"); - while (basedir) { - int blen = strlen(basedir); + while (basedir != NULL) { + size_t blen = strlen(basedir); if (blen == 0) { goto next; } bool slash = basedir[blen - 1] == '/'; - size_t n = snprintf(path, sizeof(path), "%s%s%s", - basedir, slash ? "" : "/", file); - if (n >= sizeof(path)) { + size_t n = snprintf(NULL, 0, "%s%s%s", basedir, slash ? "" : "/", file); + path = realloc(path, n + 1); + if (path == NULL) { goto next; } + snprintf(path, n + 1, "%s%s%s", basedir, slash ? "" : "/", file); if (access(path, exec ? X_OK : R_OK) != -1) { free(pathe); return path; @@ -59,6 +60,7 @@ const char *expand_path(struct mrsh_state *state, const char *file, bool exec, next: basedir = strtok(NULL, ":"); } + free(path); free(pathe); return NULL; } diff --git a/shell/task/simple_command.c b/shell/task/simple_command.c index a694326..ad876a2 100644 --- a/shell/task/simple_command.c +++ b/shell/task/simple_command.c @@ -46,7 +46,7 @@ static int run_process(struct mrsh_context *ctx, struct mrsh_simple_command *sc, // The pipeline is responsible for creating the job assert(ctx->job != NULL); - const char *path = expand_path(ctx->state, argv[0], true, false); + char *path = expand_path(ctx->state, argv[0], true, false); if (!path) { fprintf(stderr, "%s: not found\n", argv[0]); return 127; @@ -107,6 +107,8 @@ static int run_process(struct mrsh_context *ctx, struct mrsh_simple_command *sc, exit(127); } + free(path); + struct mrsh_process *process = init_child(ctx, pid); return job_wait_process(process); } -- 2.45.2