Cemetery_Gates
Cemetery_Gates

Reputation: 67

Unexpected behavior with my token function

I am trying to write a simple Shell in C. Eventually, I will implement forking of processes and piping etc. But, right now, I'm just trying to get all the logic worked out.

I have a partially working shell: When I type exit it exits... however, my token function doesn't seem to be working right.

What am I doing wrong here? I'm not sure why its seg-faulting.

Token prints out once in the while loop and then it seg-faults and crashes.

#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define MAX_BUF_SZ 1024

void checkForPipe(char *string, bool *pipe_bool);
void checkForRedirect(char *string, bool *redirect_bool);
void tokenizeInput(char *string, bool pipe, bool redirect);
int main()
{
    char *ptr;
    bool is_pipe = 0;
    bool is_redirect_out = 0;
    bool is_exit = 0;

    ptr = (char*)malloc(MAX_BUF_SZ);

    while(!is_exit)
    {
        // Diplay prompt
        char cur_dir[MAX_BUF_SZ];
        getcwd(cur_dir, MAX_BUF_SZ);
        printf("SHELL:%s$ ", cur_dir);

        fgets(ptr, MAX_BUF_SZ, stdin);
        checkForPipe(ptr, &is_pipe);
        checkForRedirect(ptr, &is_redirect_out);
        printf("pipe flag = %d\n", is_pipe);
        printf("redirect flag = %d\n", is_redirect_out);
        if(strcmp(ptr, "exit\n") == 0)
        {
            is_exit = 1;
        }

        tokenizeInput(ptr, is_pipe, is_redirect_out);

    }

    return 0;

}

void checkForPipe(char *string, bool *pipe_bool)
{
    char *check_for_pipes;
    char *clean_compare;
    check_for_pipes = (char*)malloc(MAX_BUF_SZ);
    clean_compare = (char*)malloc(MAX_BUF_SZ);

    strcpy(check_for_pipes, string);
    strcpy(clean_compare, string);

    char * token = strtok(check_for_pipes, "|");

    if(strcmp(token, clean_compare) == 0)
        {
         free(clean_compare);
         free(check_for_pipes);
        }

    else
    {
        *pipe_bool = 1;
        free(clean_compare);
        free(check_for_pipes);
    }
}

void checkForRedirect(char *string, bool *redirect_bool)
{
    char *check_for_redirects;
    char *clean_compare;
    check_for_redirects = (char*)malloc(MAX_BUF_SZ);
    clean_compare = (char*)malloc(MAX_BUF_SZ);

    strcpy(check_for_redirects, string);
    strcpy(clean_compare, string);

    char * token = strtok(check_for_redirects, ">");

    if(strcmp(token, clean_compare) == 0)
        {
         free(clean_compare);
         free(check_for_redirects);
        }

    else
    {
        *redirect_bool = 1;
        free(clean_compare);
        free(check_for_redirects);
    }

}

void tokenizeInput(char *string, bool pipe, bool redirect)
{
    char *copy_string;
    copy_string = (char*)malloc(MAX_BUF_SZ);

    strcpy(copy_string, string);

    if(pipe == 0 && redirect == 0)
    {
        char  **args = {NULL};
        char *token = strtok(copy_string, " ");
        int i = 0;
        printf("%s\n", token);
        while(token != NULL)
        {
            args[i] = token;
            strtok(NULL, " ");
            printf("%s\n", token);
            i++;
        }
    }
    /* printf("%s\n%s\n%s\n", args[0], args[1], args[2]); */
}

Upvotes: 1

Views: 77

Answers (1)

Pat. ANDRIA
Pat. ANDRIA

Reputation: 2412

The problem is on args[i] I modified your code as follows:

Supposing you have a pre-known number of token which is MAX_BUF_SZ. You allocate MAX_BUF_SZ pointers of type char*

 char **args = malloc(MAX_BUF_SZ * sizeof(char *));

and in the loop, you still have to allocate each pointer char* before using it:

while(token != NULL)
 {
            args[i] = (char *)malloc(strlen(token)+1);
            printf("%s\n", token);
            args[i] = token;
            token = strtok(NULL, " ");
            i++;
  }

The whole functions is like this:

void tokenizeInput(char *string, bool pipe, bool redirect)
{

    char *copy_string;
    copy_string = (char*)malloc(MAX_BUF_SZ);

    strcpy(copy_string, string);
    // suppose we would have MAX_BUF_SZ tokens
    char **args = malloc(MAX_BUF_SZ * sizeof(char *));
    if(pipe == 0 && redirect == 0)
    {
        char *token = strtok(copy_string, " ");
        int i = 0;
        //printf("token %s\n", token);

        while(token != NULL)
        {
            args[i] = (char *)malloc(strlen(token)+1);
            printf("%s\n", token);
            args[i] = token;
            token = strtok(NULL, " ");
            i++;
        }
    }
    /* printf("%s\n%s\n%s\n", args[0], args[1], args[2]); */
}

Here is my example running :

SHELL:D:\Users\T0180694\Documents\Mes Outils Personnels\PAN\PAN_folder$ test is essai of you and me
pipe flag = 0
redirect flag = 0
test
is
essai
of
you
and
me

Upvotes: 1

Related Questions