From 5492b1b44d77f49f09be28812ccdd38d92eb9d1e Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 26 Oct 2022 19:36:09 +0200 Subject: [PATCH] sh: Implement our own execvp() while we wait for libc. Of course, this is a very primitive execvp with hardcoded paths. If it were decent, it would be integrated into libc instantly. --- apps/src/sh.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/apps/src/sh.c b/apps/src/sh.c index dc4f0300..e1673851 100644 --- a/apps/src/sh.c +++ b/apps/src/sh.c @@ -16,6 +16,37 @@ typedef struct size_t capacity; } command; +char* shell_concat_path(const char* dirname, const char* basename) +{ + char* buf = malloc(strlen(basename) + strlen(dirname) + 6); + strlcpy(buf, dirname, strlen(dirname) + 1); + strncat(buf, basename, strlen(basename)); + return buf; +} + +void shell_execvp(char* pathname, char* const argv[]) +{ + char* new_path; + if (access(pathname, F_OK) == 0) + { + execv(pathname, argv); + return; + } + if (pathname[0] == '/') return; // We do not want to lookup absolute paths + new_path = shell_concat_path("/bin/", pathname); + if (access(new_path, F_OK) == 0) + { + execv(new_path, argv); + return; + } + free(new_path); + new_path = shell_concat_path("/usr/bin/", pathname); + execv(new_path, argv); + int saved = errno; + free(new_path); + errno = saved; +} + void show_prompt() { if (WEXITSTATUS(status)) { printf("%d [%ld]> ", WEXITSTATUS(status), getpid()); } @@ -106,22 +137,8 @@ void command_execute(command* cmd) } if (child == 0) { - if (cmd->buffer[0] != '/' && access(cmd->buffer, F_OK) < 0) // FIXME: Race condition. - { - if (errno == ENOENT) - { // Try in /bin - char* buf = malloc(cmd->size + 6); - strlcpy(buf, "/bin/", 6); - strncat(buf, cmd->buffer, cmd->size); - char* argv[] = {buf, NULL}; - execv(argv[0], argv); - } - } - else - { - char* argv[] = {cmd->buffer, NULL}; - execv(argv[0], argv); - } + char* argv[] = {cmd->buffer, NULL}; + shell_execvp(argv[0], argv); perror(cmd->buffer); exit(127); }