From 95a93a7f6653ac237403df9f286fbd71f903f7ec Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 8 Apr 2023 12:09:43 +0200 Subject: [PATCH] sh: Parse arguments --- apps/CMakeLists.txt | 4 ++- apps/sh.cpp | 66 +++++++++++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 48c143e3..91d82fea 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -7,9 +7,11 @@ function(luna_app SOURCE_FILE APP_NAME) endfunction() luna_app(init.cpp init) -luna_app(sh.cpp sh) luna_app(env.cpp env) +luna_app(sh.cpp sh) +target_link_libraries(sh PRIVATE os) + luna_app(cat.cpp cat) target_link_libraries(cat PRIVATE os) diff --git a/apps/sh.cpp b/apps/sh.cpp index a66a356c..9da7fbec 100644 --- a/apps/sh.cpp +++ b/apps/sh.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -30,17 +31,56 @@ static Result> split_command_into_argv(const char* cmd) return result; } -int main() +[[noreturn]] static void execute_command(const char* command) { + Vector argv; + bool ok = split_command_into_argv(command).try_move_value_or_error(argv, errno); + if (!ok) + { + perror("failed to parse command"); + exit(1); + } + + if (argv[0] == NULL) exit(0); + execvp(argv[0], argv.data()); + perror(argv[0]); + exit(1); +} + +int main(int argc, char** argv) +{ + StringView file; + StringView command; + + FILE* f; + + os::ArgumentParser parser; + parser.add_positional_argument(file, "file"_sv, "-"_sv); + parser.add_value_argument(command, 'c', "command"_sv, true); + parser.parse(argc, argv); + + if (!command.is_empty()) { execute_command(command.chars()); } + + if (file == "-") f = stdin; + else + { + f = fopen(file.chars(), "r"); + if (!f) + { + perror("fopen"); + return 1; + } + } + while (1) { - fputs("sh$ ", stdout); + if (file == "-") fputs("sh$ ", stdout); - char command[4096]; - char* rc = fgets(command, sizeof(command), stdin); + char cmd[4096]; + char* rc = fgets(cmd, sizeof(cmd), f); if (!rc) return 0; - if (strspn(command, " \n") == strlen(command)) continue; + if (strspn(cmd, " \n") == strlen(cmd)) continue; pid_t child = fork(); if (child < 0) @@ -49,21 +89,7 @@ int main() return 1; } - if (child == 0) - { - Vector argv; - bool ok = split_command_into_argv(command).try_move_value_or_error(argv, errno); - if (!ok) - { - perror("failed to parse command"); - return 1; - } - - if (argv[0] == NULL) return 0; - execvp(argv[0], argv.data()); - perror(argv[0]); - return 1; - } + if (child == 0) { execute_command(cmd); } if (waitpid(child, NULL, 0) < 0) {