1

My code is compiling and it is working logically for my implementation, however there are some memory leaks which is not letting me pass the checker. This is just an implementation of simple shell in C. I have spent longer than i should have trying to figure out the memory leaks.

#include "simple_shell.h"
/**                                                                                                                                                                              
 * is_interactive - check if interactive or not                                                                                                                                  
 *                                                                                                                                                                               
 * Description: check if it an interactive or not                                                                                                                                
 * Return:                                                                                                                                                                       
 **/
void free_list(list_t *head)
{
    list_t *temp;

    while (head != NULL)
    {
        temp = head;
        head = head->next;
        free(temp->str);
        free(temp);
    }
}

void is_interactive(void)
{
        if (isatty(STDIN_FILENO) == 1)
        {
                printf("$ ");
                fflush(stdout);
        }

        return;
}

/**                                                                                                                                                                              
 * main - Entry point for the simple shell                                                                                                                                       
 * Return: 0 on success, -1 on failure                                                                                                                                           
 */
int main(void)
{
    char *buffer = NULL;
    char *str_parse = NULL;
    list_t *head;
    int listt_len;
    char **argv;
    int i;

    while (1)
    {
        is_interactive();
        buffer = read_input();

        if (buffer == NULL)
            break;

        if (strcmp(buffer, "exit\n") == 0)
        {
            free(buffer);
            break;
        }

        str_parse = strdup(buffer);
        head = tokenize_input(str_parse);
        if (head == NULL)
        {
            free(buffer);
            free(str_parse);
            continue;
        }

        listt_len = list_len(head);
        argv = malloc(sizeof(char *) * (listt_len + 1));

        for (i = 0; head != NULL; i++)
        {
            argv[i] = head->str;
            head = head->next;
        }
        argv[i] = NULL;

        execute_command(argv);

        free(argv);
        free(buffer);
        free(str_parse);
        free_list(head);
    }

    return (0);
}

#include "simple_shell.h"

/**                                                                                                                                                                              
 * count_tokens - Counts the number of tokens in a string                                                                                                                        
 * @str: The input string                                                                                                                                                        
 * @delim: The delimiter string                                                                                                                                                  
 * Return: The number of tokens                                                                                                                                                  
 */
list_t *tokenize_input(char *input)
{
    const char *delim = " \n";
    char *token;
    list_t *head = NULL;

    token = strtok(input, delim);
    while (token != NULL)
    {
        add_node_end(&head, token);
        token = strtok(NULL, delim);
    }

    return (head);
}

#include "simple_shell.h"

/**                                                                                                                                                                              
 * read_input - Reads user input                                                                                                                                                 
 * Return: The input string, or NULL if EOF is reached                                                                                                                           
 */
char *read_input(void)
{
    char *buffer = NULL;
    size_t count = 0;
    ssize_t chars_read;
    
    chars_read = getline(&buffer, &count, stdin);

    if (chars_read == -1)
    {
        free(buffer);
        return NULL;
    }

    return buffer;
}

/**                                                                                                                                                                              
 * free_memory - Frees the memory allocated for command and arguments                                                                                                            
 * @argv: The command and its arguments                                                                                                                                          
 * @num_tokens: The number of tokens                                                                                                                                             
 * @str_parse: The parsed string                                                                                                                                                 
 */
void free_memory(char **argv, int num_tokens, char *str_parse)
{
    int i;
    
    for (i = 0; i < num_tokens; i++)
    {
        free(argv[i]);
    }
    free(argv);
    free(str_parse);
}

#include "simple_shell.h"

extern char **environ;
/**                                                                                                                                                                              
 * execute_command - Executes the given command                                                                                                                                  
 * @argv: The command and its arguments                                                                                                                                          
 */
void execute_command(char **argv)
{
    pid_t pid;
    
    pid = fork();

    if (pid == 0)
    {
        if (argv != NULL && execve(argv[0], argv, environ) == -1)
            printf("%s: No such file or directory\n", argv[0]);

        exit(0);
    }
    else if (pid > 0)
    {
        wait(NULL);
    }
    else
    {
        perror("fork");
        exit(-1);
    }
    return;
}

#include "simple_shell.h"
/**                                                                                                                                                                              
 * print_list - prints all the elements of a list_t list                                                                                                                         
 * @h: pointer to the head of the list                                                                                                                                           
 *                                                                                                                                                                               
 * Return: the number of nodes in the list                                                                                                                                       
 */
size_t print_list(const list_t *h)
{
        size_t count = 0;

        while (h != NULL)
        {
                if (h->str != NULL)
                {
                        printf("[%u] %s\n", h->len, h->str);
                }
                else
                {
                        printf("[0] (nil)\n");
                }

                h = h->next;
                count++;
        }
        return (count);
}

#include "simple_shell.h"
/**                                                                                                                                                                              
 * list_len - Returns the number of elements in a linked list_t list.                                                                                                            
 * @h: Pointer to the head node of the list.                                                                                                                                     
 *                                                                                                                                                                               
 * Return: The number of elements in the list.                                                                                                                                   
 */
size_t list_len(const list_t *h)
{
    size_t count = 0;

    if (h == NULL)
    {
            return (0);
    }
    while (h != NULL)
    {
            count++;
            h = h->next;
    }

    return (count);
}

#include "simple_shell.h"
/**                                                                                                                                                                              
 * add_node_end - adds a new node at the end of a list_t list                                                                                                                    
 * @head: pointer to the head of the list                                                                                                                                        
 * @str: string to be added to the new node                                                                                                                                      
 *                                                                                                                                                                               
 * Return: address of the new element or NULL if it failed                                                                                                                       
 */
list_t *add_node_end(list_t **head, const char *str)
{
        int i, n = 0;
        list_t *new_node;
        list_t *temp;

        new_node = malloc(sizeof(list_t));
        if (new_node == NULL)
                return (NULL);

        for (i = 0; str[i] != '\0'; i++)
                n++;

        new_node->len = i;
        new_node->str = strdup(str);
        new_node->next = NULL;

        if (*head == NULL)
        {
                *head = new_node;
                return (new_node);
        }

        temp = *head;

        while (temp->next != NULL)
                temp = temp->next;

        temp->next = new_node;

        return (new_node);
}
    ==4930== Process terminating with default action of signal 2 (SIGINT)
    ==4930==    at 0x4962002: read (read.c:26)
    ==4930==    by 0x48E4BCE: _IO_file_underflow@@GLIBC_2.2.5 (fileops.c:517)
    ==4930==    by 0x48D7747: getdelim (iogetdelim.c:73)
    ==4930==    by 0x10981B: read_input (in /root/holbertonschool-simple_shell/hsh)
    ==4930==    by 0x1095FE: main (in /root/holbertonschool-simple_shell/hsh)
    ==4930== 
    ==4930== HEAP SUMMARY:
    ==4930==     in use at exit: 240 bytes in 9 blocks
    ==4930==   total heap usage: 22 allocs, 13 frees, 2,853 bytes allocated
    ==4930== 
    ==4930== 120 (72 direct, 48 indirect) bytes in 3 blocks are definitely lost in loss record 4 of 4
    ==4930==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==4930==    by 0x109400: add_node_end (in /root/holbertonschool-simple_shell/hsh)
    ==4930==    by 0x1097A0: tokenize_input (in /root/holbertonschool-simple_shell/hsh)
    ==4930==    by 0x109651: main (in /root/holbertonschool-simple_shell/hsh)
    ==4930== 
    ==4930== LEAK SUMMARY:
    ==4930==    definitely lost: 72 bytes in 3 blocks
    ==4930==    indirectly lost: 48 bytes in 5 blocks
    ==4930==      possibly lost: 0 bytes in 0 blocks
    ==4930==    still reachable: 120 bytes in 1 blocks
    ==4930==         suppressed: 0 bytes in 0 blocks
    ==4930== Reachable blocks (those to which a pointer was found) are not shown.
    ==4930== To see them, rerun with: --leak-check=full --show-leak-kinds=all
    ==4930== 
    ==4930== For lists of detected and suppressed errors, rerun with: -s
    ==4930== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

I have tried to figure out on my own but I believe i am freeing the memory where needed but cannot seem to figure out where else its leaking from.

Paul Floyd
  • 5,530
  • 5
  • 29
  • 43

0 Answers0