msh

simple shell implementation
Index Commits Files Refs README LICENSE
commit d302fe8497fa275490bed2013d43c274416e02cb
parent 8425a67a30ea080d91d0ae8969c37f7be70932c1
Author: mjkloeckner <martin.cachari@gmail.com>
Date:   Sat,  6 May 2023 21:55:22 -0300

make buffer_read_line() and buffer_split() dynamic

Diffstat:
MMakefile | 2+-
Mmsh.c | 116+++++++++++++++++++++++++++++++++++++++++--------------------------------------
2 files changed, 61 insertions(+), 57 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
 CC := gcc
-CFLAGS := -Wall -Wshadow -pedantic -ansi -std=c99
+CFLAGS := -D_POSIX_C_SOURCE=199309L -Wall -Wshadow -pedantic -ansi -std=c99
 SRCS := $(wildcard *.c)
 OBJS := $(SRCS:.c=.o)
 
diff --git a/msh.c b/msh.c
@@ -6,64 +6,72 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
-#define    READLINE_BUFFER_INIT_SIZE     2
+#define    READLINE_BUFFER_INIT_SIZE    2
 #define TOKENS_BUFFER_INIT_SIZE        16
 
 static bool run = true;
 static size_t alloc_len;
 
-void buffer_clear(char *buf, size_t *len) {
-    for (size_t i = 0; i < *len; i++)
+void buffer_clear(char *buf) {
+    size_t len = strlen(buf);
+    for (size_t i = 0; i < len; i++)
         buf[i] = '\0';
-
-    *len = 0;
 }
 
-void buffer_read_line(char *buffer, size_t *len) {
+char *buffer_read_line(void) {
     int c;
-    char *tmp;
+    char *s, *aux;
+    size_t used_size;
+
+    if(!(s = malloc(alloc_len = READLINE_BUFFER_INIT_SIZE)))
+        return NULL;
 
-    /* read line into buffer */
-    while(1) {
-        c = fgetc(stdin);
+    used_size = 0;
+    while (1) {
+        c = getchar();
         if((c == '\n') || (c == EOF)) break;
 
-        if((*len + 2 == alloc_len)) {
-            alloc_len += alloc_len;
-            if((tmp = realloc(buffer, alloc_len)) == NULL) return;
-            buffer = tmp;
+        if(used_size == (alloc_len - 1)) {
+            if(!(aux = realloc(s, alloc_len += alloc_len))) {
+                perror("msh");
+                free(s);
+                return NULL;
+            }
+            s = aux;
         }
-
-        buffer[(*len)++] = c;
+        s[used_size++] = c;
     }
-    buffer[*len] = '\0';
+    s[used_size] = '\0';
     if (c == EOF) run = false;
+    return s;
 }
 
-void buffer_split(char *b, char ***tokens, size_t *tokens_count) {
-    if(b == NULL) return;
-
-    char **tmp;
-    size_t token_alloc;
-
-    *tokens_count = 0;
-
-    if(*tokens != NULL) return; 
-
-    *tokens = malloc((sizeof(char *) * TOKENS_BUFFER_INIT_SIZE));
-    token_alloc = TOKENS_BUFFER_INIT_SIZE;
-    if (*tokens == NULL) return;
-
-    (*tokens)[*tokens_count] = strtok(b, " ");
-    while((*tokens)[*tokens_count] != NULL) {
-        (*tokens)[++(*tokens_count)] = strtok(NULL, " ");
-        if (*tokens_count == token_alloc) {
-            token_alloc += token_alloc;
-            tmp = realloc(*tokens, sizeof(char *) * token_alloc);
-            if(tmp == NULL) return;
-            *tokens = tmp;
+char **buffer_split_delim(char *b, size_t *t) {
+    char *p, **tokens, **aux;
+    size_t tokens_count, tokens_alloc;
+
+    tokens_alloc = TOKENS_BUFFER_INIT_SIZE;
+    tokens = malloc(sizeof(char*) * TOKENS_BUFFER_INIT_SIZE);
+
+    tokens_count = 0;
+    for(p = b; (p = strtok(p, " ")); p = NULL) {
+        if((tokens_count + 1) == tokens_alloc) {
+            if(!(aux = realloc(tokens, tokens_alloc += tokens_alloc))) {
+                perror("msh");
+                for(size_t i = 0; i < tokens_count; i++)
+                    free(tokens[i]);
+                free(tokens);
+                return NULL;
+            }
+            tokens = aux;
         }
+
+        tokens[tokens_count] = calloc(strlen(p) + 1, sizeof(char));
+        strcpy(tokens[tokens_count++], p);
     }
+
+    *t = tokens_count;
+    return tokens;
 }
 
 void msh_execute(char **argv) {
@@ -73,7 +81,8 @@ void msh_execute(char **argv) {
     pid = fork();
     if (pid == 0) {
         /* child process */
-        if(execvp(argv[0], argv) < 0) perror("msh");
+        if(execvp(argv[0], argv) < 0)
+            perror(argv[0]);
 
         exit(EXIT_FAILURE);
     }
@@ -89,30 +98,25 @@ void msh_execute(char **argv) {
 
 void msh_loop(void) {
     char *buffer, **tokens;
-    size_t len, tokens_count;
-
-    buffer = malloc(alloc_len = READLINE_BUFFER_INIT_SIZE);
+    size_t tokens_count;
 
-    len = 0;
     while (run) {
-        buffer_clear(buffer, &len);
-
         printf("> ");
-
-        buffer_read_line(buffer, &len);
-
-        tokens = NULL;
-        tokens_count = 0;
-        buffer_split(buffer, &tokens, &tokens_count);
+        buffer = buffer_read_line();
+        /* printf("%s\n", buffer); */
+        tokens = buffer_split_delim(buffer, &tokens_count);
 
         msh_execute(tokens);
+        for (size_t token = 0; token < tokens_count; token++)
+            free(tokens[token]);
+        free(buffer);
     }
 
-    for (size_t token = 0; token < tokens_count; token++)
-        free(tokens[token]);
+    /* for (size_t token = 0; token < tokens_count; token++) */
+    /*     free(tokens[token]); */
 
-    free(tokens);
-    free(buffer);
+    /* free(tokens); */
+    /* free(buffer); */
 }
 
 int main (void) {