From e96ae4b4a2f94ce6d28166e120de6774cec73173 Mon Sep 17 00:00:00 2001 From: Aleksandr Lebedev Date: Thu, 19 Feb 2026 16:13:34 +0100 Subject: [PATCH] Switched from GNU Readline to custom Readline function to make arsh more compatible with other Unix-Like systems - Fixed small memory leak --- README.org | 5 +++-- main.c | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/README.org b/README.org index 82df2c3..aae4ce0 100644 --- a/README.org +++ b/README.org @@ -6,8 +6,9 @@ Simple shell for Unix-like systems written in C, that has a funny name (for germ - ~cd~ builtin command - ~exit~ builtin command - ~CTRL+C~ stops running command +- Custom ~readline~ function * Build -To build it, you need ~readline~ library. Then use +To build it, you don't need any external dependencies. Example with ~gcc~: #+begin_src shell -gcc main.c -O3 -lreadline -o arsh +gcc main.c -O3 -o arsh #+end_src diff --git a/main.c b/main.c index 4df6d87..4dc2c3d 100644 --- a/main.c +++ b/main.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -20,6 +19,31 @@ void sigint_handler(int signo) } siglongjmp(restart_jmp_buf, restart_value); } +static constexpr size_t max_line = 1024; +static char string_buffer[max_line]; +char* readline(char* print) +{ + if(print) + { + printf("%s", print); + } + if((fgets(string_buffer, max_line, stdin) == NULL) && ferror(stdin)) + { + perror("fgets error"); + } + + size_t length = strlen(string_buffer); + if(length == 0) + { + return NULL; + } + //Remove trailing \n + if (length > 0 && string_buffer[length - 1] == '\n') + { + string_buffer[length - 1] = '\0'; + } + return string_buffer; +} char** split_input(char* input) { @@ -71,9 +95,14 @@ int main() char* input = readline("arsh> "); if(input == NULL) //CTRL + D { - continue; + printf("\nexit\n"); + exit(0); } char** command = split_input(input); + if(command[0] == NULL) + { + goto cleanup; + } if(strcmp(command[0], "cd") == 0) { @@ -82,7 +111,7 @@ int main() perror(command[1]); } - continue; //skip fork() + goto cleanup; //skip fork() } if(strcmp(command[0], "exit") == 0) { @@ -111,7 +140,8 @@ int main() waitpid(child_pid, &stat_loc, WUNTRACED); } - free(input); +cleanup: + free(command); } }