msh

simple shell implementation
Index Commits Files Refs README LICENSE
commit 61e7e9a89e53e489a5e8e7368521d41398e3aee7
parent 5d06822349e135a141df1b6088c1e513ea28cbd9
Author: mjkloeckner <martinjkloeckner@gmail.com>
Date:   Tue,  2 May 2023 00:29:02 -0300

fully functional shell implementation

Diffstat:
Mmsh.c | 66++++++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 42 insertions(+), 24 deletions(-)
diff --git a/msh.c b/msh.c
@@ -2,10 +2,12 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
-#define    READLINE_BUFFER_INIT_SIZE         1000
-#define READLINE_BUFFER_GROWTH_FACTOR    0.5f
-#define TOKENS_BUFFER_INIT_SIZE            16
+#define    READLINE_BUFFER_INIT_SIZE     2
+#define TOKENS_BUFFER_INIT_SIZE        16
 
 static bool run = true;
 static size_t alloc_len;
@@ -27,7 +29,7 @@ void buffer_read_line(char *buffer, size_t *len) {
         if((c == '\n') || (c == EOF)) break;
 
         if((*len + 2 == alloc_len)) {
-            alloc_len += alloc_len * READLINE_BUFFER_GROWTH_FACTOR;
+            alloc_len += alloc_len;
             if((tmp = realloc(buffer, alloc_len)) == NULL) return;
             buffer = tmp;
         }
@@ -38,13 +40,12 @@ void buffer_read_line(char *buffer, size_t *len) {
     if (c == EOF) run = false;
 }
 
-void buffer_split(char *b, size_t *len, char ***tokens, size_t *tokens_count) {
+void buffer_split(char *b, char ***tokens, size_t *tokens_count) {
     if(b == NULL) return;
 
+    char **tmp;
     size_t token_alloc;
-    char *start, **tmp;
 
-    start = b;
     *tokens_count = 0;
 
     if(*tokens != NULL) return; 
@@ -57,23 +58,42 @@ void buffer_split(char *b, size_t *len, char ***tokens, size_t *tokens_count) {
     while((*tokens)[*tokens_count] != NULL) {
         (*tokens)[++(*tokens_count)] = strtok(NULL, " ");
         if (*tokens_count == token_alloc) {
-            token_alloc += TOKENS_BUFFER_INIT_SIZE;
+            token_alloc += token_alloc;
             tmp = realloc(*tokens, sizeof(char *) * token_alloc);
             if(tmp == NULL) return;
             *tokens = tmp;
         }
     }
+}
+
+void msh_execute(char **argv) {
+    int status;
+    pid_t pid;
 
-    b = start;
+    pid = fork();
+    if (pid == 0) {
+        /* child process */
+        if(execvp(argv[0], argv) < 0) perror("msh");
+
+        exit(EXIT_FAILURE);
+    }
+    else if (pid < 0) {
+        perror("msh: could not fork");
+    }
+    else {
+        do {
+            waitpid(pid, &status, WUNTRACED);
+        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+    }
 }
 
 void msh_loop(void) {
-    char *buffer;
-    size_t len;
+    char *buffer, **tokens;
+    size_t len, tokens_count;
 
-    len = 0;
     buffer = malloc(alloc_len = READLINE_BUFFER_INIT_SIZE);
 
+    len = 0;
     while (run) {
         buffer_clear(buffer, &len);
 
@@ -81,23 +101,21 @@ void msh_loop(void) {
 
         buffer_read_line(buffer, &len);
 
-        /* printf("%s\n", buffer); */
-
-        char **tokens = NULL;
-        size_t tokens_count = 0;
-        buffer_split(buffer, &len, &tokens, &tokens_count);
+        tokens = NULL;
+        tokens_count = 0;
+        buffer_split(buffer, &tokens, &tokens_count);
 
-        printf("tokens_count: %ld\n", tokens_count);
-        for(size_t t = 0; t < tokens_count; t++)
-            printf("%s\n", tokens[t]);
+        msh_execute(tokens);
     }
+
+    for (size_t token = 0; token < tokens_count; token++)
+        free(tokens[token]);
+
+    free(tokens);
+    free(buffer);
 }
 
 int main (void) {
-    /* load config files */
-
     msh_loop();
-
-    /* cleanup */
     return 0;
 }