From 53e3c1e2766a7a3166c87c7129396b9c2cd15052 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Sat, 26 Jun 2021 21:20:36 -0400 Subject: [PATCH 1/7] standardize format --- src/include/array.h | 1 - src/include/builtins.h | 2 ++ src/include/console_line.h | 2 ++ src/include/loop.h | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/include/array.h b/src/include/array.h index fef9b3a..cdf048a 100644 --- a/src/include/array.h +++ b/src/include/array.h @@ -29,5 +29,4 @@ void insert_string_array(StringArray *string_array, char *string); void delete_string_array(StringArray *string_array, int index); void free_string_array(StringArray *string_array); - #endif diff --git a/src/include/builtins.h b/src/include/builtins.h index ccaebbf..4ffa2d5 100644 --- a/src/include/builtins.h +++ b/src/include/builtins.h @@ -19,6 +19,8 @@ #ifndef _MYSHELLIN_BUILTINS #define _MYSHELLIN_BUILTINS bool is_builtin(char *command); + void run_builtin(StringArray *string_array); + void exit_shell(StringArray *string_array); #endif diff --git a/src/include/console_line.h b/src/include/console_line.h index 6b0803c..0b4db5b 100644 --- a/src/include/console_line.h +++ b/src/include/console_line.h @@ -16,6 +16,8 @@ #ifndef _MYSHELLIN_CONSOLE_LINE #define _MYSHELLIN_CONSOLE_LINE char *get_user(); + char *get_working_directory(); + void print_input_line(); #endif diff --git a/src/include/loop.h b/src/include/loop.h index adc2695..d60f051 100644 --- a/src/include/loop.h +++ b/src/include/loop.h @@ -16,5 +16,6 @@ #ifndef _MYSHELLIN_LOOP #define _MYSHELLIN_LOOP void remove_new_line(char *line); + void loop(); #endif From 907af65b94d4f560c6054ddbb51a8501263c8815 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Sat, 26 Jun 2021 22:38:22 -0400 Subject: [PATCH 2/7] move input to separate file --- src/console_line.c | 27 +++++++++++++++++++++++++++ src/include/console_line.h | 4 ++++ src/loop.c | 24 ++---------------------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/console_line.c b/src/console_line.c index 7ea5e34..99bfce2 100644 --- a/src/console_line.c +++ b/src/console_line.c @@ -21,6 +21,7 @@ #include #include #include "color.h" +#include "console_line.h" /** * Get the logged in user's username. @@ -57,3 +58,29 @@ void print_input_line() { printf(BRIGHT_CYAN "%s" MAGENTA "@" RED "localhost" MAGENTA ":" BLUE "%s" MAGENTA "$ " RESET, name, cwd); free(cwd); } + +char *get_console_input() { + size_t buffer_size = 0; + char *line = NULL; + + if (getline(&line, &buffer_size, stdin) == -1) { + if (feof(stdin)) { + // the stdin was closed, this usually happens for CTRL-D + printf("\n"); + if (line != NULL) { + free(line); + line = NULL; + } + exit(EXIT_SUCCESS); + } + else { + perror("getline() error: "); + if (line != NULL) { + free(line); + line = NULL; + } + exit(EXIT_FAILURE); + } + } + return line; +} diff --git a/src/include/console_line.h b/src/include/console_line.h index 0b4db5b..8071ce5 100644 --- a/src/include/console_line.h +++ b/src/include/console_line.h @@ -15,9 +15,13 @@ #ifndef _MYSHELLIN_CONSOLE_LINE #define _MYSHELLIN_CONSOLE_LINE +#define CONSOLE_BUFFER_SIZE 1024 + char *get_user(); char *get_working_directory(); void print_input_line(); + +char *get_console_input(); #endif diff --git a/src/loop.c b/src/loop.c index cfaf81f..23953bc 100644 --- a/src/loop.c +++ b/src/loop.c @@ -33,30 +33,10 @@ void remove_new_line(char* line) { * This is the loop that checks for user input and acts on it. */ void loop() { - size_t buffer_size = 0; - char *line = NULL; - while (1) { print_input_line(); - if (getline(&line, &buffer_size, stdin) == -1) { - if (feof(stdin)) { - // the stdin was closed, this usually happens for CTRL-D - printf("\n"); - if (line != NULL) { - free(line); - line = NULL; - } - exit(EXIT_SUCCESS); - } - else { - perror("getline() error: "); - if (line != NULL) { - free(line); - line = NULL; - } - exit(EXIT_FAILURE); - } - } + + char *line = get_console_input(); remove_new_line(line); From 4ea527064ae1d6c2def0352ce92225cccf6b12e2 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Sat, 26 Jun 2021 22:48:19 -0400 Subject: [PATCH 3/7] add missing documentation for functions --- src/array.c | 18 ++++++++++++++++++ src/builtins.c | 13 +++++++++++++ src/console_line.c | 4 ++++ 3 files changed, 35 insertions(+) diff --git a/src/array.c b/src/array.c index c09ab80..7ddfcf9 100644 --- a/src/array.c +++ b/src/array.c @@ -16,11 +16,20 @@ #include #include "array.h" +/** + * Create a String Array by initializing its structure. + * @param string_array The String Array to create. + */ void create_string_array(StringArray *string_array) { string_array->array = NULL; string_array->size = 0; } +/** + * Insert a string into the String Array. + * @param string_array The String Array to insert into. + * @param string The string to insert into the String Array. + */ void insert_string_array(StringArray *string_array, char *string) { if (string_array->size == 0) { string_array->array = malloc(sizeof(char *)); @@ -33,6 +42,11 @@ void insert_string_array(StringArray *string_array, char *string) { string_array->size++; } +/** + * Delete a string from the String Array. + * @param string_array The String Array to delete from. + * @param index The index in the String Array to delete. + */ void delete_string_array(StringArray *string_array, int index) { if (string_array->size > 0 && string_array->size > index) { for (int i = index; i < string_array->size - 1; i++) { @@ -48,6 +62,10 @@ void delete_string_array(StringArray *string_array, int index) { } } +/** + * Free the String Array and all of its strings. + * @param string_array The String Array to free. + */ void free_string_array(StringArray *string_array) { for (int i = 0; i < string_array->size; i++) { free(string_array->array[i]); diff --git a/src/builtins.c b/src/builtins.c index 4648ad9..bb70815 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -18,6 +18,11 @@ #include "array.h" #include "builtins.h" +/** + * Check if the command is a builtin or not. + * @param command String with the command name to check. + * @return Returns true if it's a builtin or false otherwise. + */ bool is_builtin(char *command) { if (strcmp(command, "exit") == 0) { return true; @@ -30,12 +35,20 @@ bool is_builtin(char *command) { return false; } +/** + * Run the builtin command. + * @param string_array An array of strings containing the arguments to run. + */ void run_builtin(StringArray *string_array) { if (strcmp(string_array->array[0], "exit") == 0) { exit_shell(string_array); } } +/** + * Exit the shell. + * @param string_array The arguments that were used to call exit. This is used to free the memory before exit. + */ void exit_shell(StringArray *string_array) { free_string_array(string_array); exit(EXIT_SUCCESS); diff --git a/src/console_line.c b/src/console_line.c index 99bfce2..58105e9 100644 --- a/src/console_line.c +++ b/src/console_line.c @@ -59,6 +59,10 @@ void print_input_line() { free(cwd); } +/** + * Get input from the console. + * @return Returns a string input by the user. + */ char *get_console_input() { size_t buffer_size = 0; char *line = NULL; From 60004f08dc7a6d3ca3b6a704407af67406fa88c4 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Sat, 26 Jun 2021 22:51:39 -0400 Subject: [PATCH 4/7] rename string array variable to make it clear what it is --- src/builtins.c | 14 +++++++------- src/loop.c | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index bb70815..a677774 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -37,19 +37,19 @@ bool is_builtin(char *command) { /** * Run the builtin command. - * @param string_array An array of strings containing the arguments to run. + * @param args An array of strings containing the arguments to run. */ -void run_builtin(StringArray *string_array) { - if (strcmp(string_array->array[0], "exit") == 0) { - exit_shell(string_array); +void run_builtin(StringArray *args) { + if (strcmp(args->array[0], "exit") == 0) { + exit_shell(args); } } /** * Exit the shell. - * @param string_array The arguments that were used to call exit. This is used to free the memory before exit. + * @param args The arguments that were used to call exit. This is used to free the memory before exit. */ -void exit_shell(StringArray *string_array) { - free_string_array(string_array); +void exit_shell(StringArray *args) { + free_string_array(args); exit(EXIT_SUCCESS); } diff --git a/src/loop.c b/src/loop.c index 23953bc..6721ec3 100644 --- a/src/loop.c +++ b/src/loop.c @@ -40,13 +40,13 @@ void loop() { remove_new_line(line); - StringArray string_array; - create_string_array(&string_array); + StringArray args; + create_string_array(&args); char *saveptr = NULL; char *token = strtok_r(line, " ", &saveptr); while (token) { - insert_string_array(&string_array, token); + insert_string_array(&args, token); token = strtok_r(NULL, " ", &saveptr); } if (line != NULL) { @@ -55,14 +55,14 @@ void loop() { } // The user didn't type anything so restart the loop - if (string_array.size == 0) { + if (args.size == 0) { continue; } - if (is_builtin(string_array.array[0])) { - run_builtin(&string_array); + if (is_builtin(args.array[0])) { + run_builtin(&args); } - free_string_array(&string_array); + free_string_array(&args); } } From 8776bbd6fa701e5d15e6daec2856ab0949195738 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Sat, 26 Jun 2021 23:05:27 -0400 Subject: [PATCH 5/7] add hostname --- src/console_line.c | 29 ++++++++++++++++++++++++++--- src/include/console_line.h | 6 +++++- src/include/loop.h | 2 -- src/loop.c | 10 ---------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/console_line.c b/src/console_line.c index 58105e9..49301b2 100644 --- a/src/console_line.c +++ b/src/console_line.c @@ -18,21 +18,42 @@ #include #include #include +#include #include #include #include "color.h" #include "console_line.h" +/** + * Remove new line from the end of a string. + * @param line The string to remove the new line from. + */ +void remove_new_line(char* line) { + line[strcspn(line, "\n")] = 0; +} + /** * Get the logged in user's username. * @return Returns the logged in user's username. */ -char *get_user() { +char *get_username() { struct passwd *pass; pass = getpwuid(getuid()); return pass->pw_name; } +/** + * Get the hostname of the machine. + * @return Returns the hostname. + */ +char *get_hostname() { + char hostname[HOST_NAME_MAX + 1]; + gethostname(hostname, HOST_NAME_MAX + 1); + char *result = malloc((HOST_NAME_MAX + 1) * sizeof(char)); + strcpy(result, hostname); + return result; +} + /** * Get the current working directory of the shell. * @return Returns the current working directory. @@ -53,9 +74,10 @@ char *get_working_directory() { * Print the console line before the user input. */ void print_input_line() { - char *name = get_user(); + char *username = get_username(); + char *hostname = get_hostname(); char *cwd = get_working_directory(); - printf(BRIGHT_CYAN "%s" MAGENTA "@" RED "localhost" MAGENTA ":" BLUE "%s" MAGENTA "$ " RESET, name, cwd); + printf(BRIGHT_CYAN "%s" MAGENTA "@" RED "%s" MAGENTA ":" BLUE "%s" MAGENTA "$ " RESET, username, hostname, cwd); free(cwd); } @@ -86,5 +108,6 @@ char *get_console_input() { exit(EXIT_FAILURE); } } + remove_new_line(line); return line; } diff --git a/src/include/console_line.h b/src/include/console_line.h index 8071ce5..e1f85eb 100644 --- a/src/include/console_line.h +++ b/src/include/console_line.h @@ -17,7 +17,11 @@ #define _MYSHELLIN_CONSOLE_LINE #define CONSOLE_BUFFER_SIZE 1024 -char *get_user(); +void remove_new_line(char *line); + +char *get_username(); + +char *get_hostname(); char *get_working_directory(); diff --git a/src/include/loop.h b/src/include/loop.h index d60f051..0586ad7 100644 --- a/src/include/loop.h +++ b/src/include/loop.h @@ -15,7 +15,5 @@ #ifndef _MYSHELLIN_LOOP #define _MYSHELLIN_LOOP -void remove_new_line(char *line); - void loop(); #endif diff --git a/src/loop.c b/src/loop.c index 6721ec3..e7b6087 100644 --- a/src/loop.c +++ b/src/loop.c @@ -21,14 +21,6 @@ #include "builtins.h" #include "console_line.h" -/** - * Remove new line from the end of a string. - * @param line The string to remove the new line from. - */ -void remove_new_line(char* line) { - line[strcspn(line, "\n")] = 0; -} - /** * This is the loop that checks for user input and acts on it. */ @@ -38,8 +30,6 @@ void loop() { char *line = get_console_input(); - remove_new_line(line); - StringArray args; create_string_array(&args); From 90019c46ba73428fbec580c63dfb9361cdd9ddd0 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Sat, 26 Jun 2021 23:06:11 -0400 Subject: [PATCH 6/7] free hostname --- src/console_line.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/console_line.c b/src/console_line.c index 49301b2..4207cfb 100644 --- a/src/console_line.c +++ b/src/console_line.c @@ -78,6 +78,7 @@ void print_input_line() { char *hostname = get_hostname(); char *cwd = get_working_directory(); printf(BRIGHT_CYAN "%s" MAGENTA "@" RED "%s" MAGENTA ":" BLUE "%s" MAGENTA "$ " RESET, username, hostname, cwd); + free(hostname); free(cwd); } From 344fbc4eb52e546e6853d4e29a3063073a3d13e8 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Sat, 26 Jun 2021 23:13:51 -0400 Subject: [PATCH 7/7] validate calls to malloc and realloc --- src/array.c | 33 +++++++++++++++++++++++++++++---- src/console_line.c | 4 ++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/array.c b/src/array.c index 7ddfcf9..1cd8eb1 100644 --- a/src/array.c +++ b/src/array.c @@ -13,6 +13,7 @@ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include "array.h" @@ -33,11 +34,23 @@ void create_string_array(StringArray *string_array) { void insert_string_array(StringArray *string_array, char *string) { if (string_array->size == 0) { string_array->array = malloc(sizeof(char *)); + if (string_array->array == NULL) { + fprintf(stderr, "malloc failed"); + exit(EXIT_FAILURE); + } } else { string_array->array = realloc(string_array->array, (string_array->size + 1) * sizeof(char *)); + if (string_array->array == NULL) { + fprintf(stderr, "realloc failed"); + exit(EXIT_FAILURE); + } } string_array->array[string_array->size] = malloc(sizeof(string)); + if (string_array->array == NULL) { + fprintf(stderr, "malloc failed"); + exit(EXIT_FAILURE); + } strcpy(string_array->array[string_array->size], string); string_array->size++; } @@ -53,11 +66,19 @@ void delete_string_array(StringArray *string_array, int index) { free(string_array->array[i]); string_array->array[i] = NULL; string_array->array[i] = malloc(sizeof(string_array->array[i + 1])); + if (string_array->array[i] == NULL) { + fprintf(stderr, "malloc failed"); + exit(EXIT_FAILURE); + } strcpy(string_array->array[i], string_array->array[i + 1]); } free(string_array->array[string_array->size - 1]); string_array->array[string_array->size - 1] = NULL; string_array->array = realloc(string_array->array, (string_array->size - 1) * sizeof(char *)); + if (string_array->array == NULL) { + fprintf(stderr, "realloc failed"); + exit(EXIT_FAILURE); + } string_array->size--; } } @@ -68,10 +89,14 @@ void delete_string_array(StringArray *string_array, int index) { */ void free_string_array(StringArray *string_array) { for (int i = 0; i < string_array->size; i++) { - free(string_array->array[i]); - string_array->array[i] = NULL; + if (string_array->array[i] != NULL) { + free(string_array->array[i]); + string_array->array[i] = NULL; + } + } + if (string_array->array != NULL) { + free(string_array->array); + string_array->array = NULL; } - free(string_array->array); - string_array->array = NULL; string_array->size = 0; } diff --git a/src/console_line.c b/src/console_line.c index 4207cfb..3c1413c 100644 --- a/src/console_line.c +++ b/src/console_line.c @@ -50,6 +50,10 @@ char *get_hostname() { char hostname[HOST_NAME_MAX + 1]; gethostname(hostname, HOST_NAME_MAX + 1); char *result = malloc((HOST_NAME_MAX + 1) * sizeof(char)); + if (result == NULL) { + fprintf(stderr, "malloc failed"); + exit(EXIT_FAILURE); + } strcpy(result, hostname); return result; }