0

So I'm looping through readdir() function calls and adding the resulting file name to a new node in a linked list. After fixing an issue by setting file_list = add_file_node(), I'm running into and issue where the dir_list loop is having problems accessing the directory.

hls: cannot access hls: cannot access h: No such file or directory

code:

#include "header.h"


/**
 * main - main ls function
 *
 * @argc: argument count
 * @argv: argument vector
 *
 * Return: 0, or the errno of the error
 */
int main(int argc, char **argv)
{
    struct dirent *read;
    char dir[400], error_message[400], format, hidden;
    int i, j, dir_count, max_src_bytes = 397;
    dir_list_t *dir_list, *dir_node;
    file_list_t *file_list;
    DIR *dirp;
    int errno;

    format = ' ';
    hidden = ' ';
    dir_count = 0;

    strcpy(dir, ".");
    for (i = 1; i < argc; i++)
    {
        if (argv[i][0] == '-')
        {
            for (j = 1; argv[i][j]; j++)
            {
                if (argv[i][j] == '1')
                    format = '1';
                else if (argv[i][j] == 'l')
                    format = 'l';
                if (argv[i][j] == 'a')
                    hidden = 'a';
                else if (argv[i][j] == 'A')
                    hidden = 'A';
            }
        }
        else
        {
            memset(dir, 0, strlen(dir));
            strcpy(dir, argv[i]);
            dir_list = add_dir_list(&dir_list, dir);
            dir_count++;
        }
    }

    if (dir_count == 0)
        dir_list = add_dir_list(&dir_list, dir);


    for (dir_node = dir_list; dir_node != NULL; dir_node = dir_node->next)
    {
        dirp = opendir(dir_node->dir);
        if (dirp == NULL)
        {
            strcpy(error_message, "hls: cannot access ");
            max_src_bytes = 381;
            perror(strncat(error_message, dir_node->dir, max_src_bytes));
            return (errno);
        }
        if (dir_count > 1)
            printf("%s:\n", dir_node->dir);


        while ((read = readdir(dirp)) != NULL)
        {
            file_list = add_file_list(&file_list, read->d_name);
        }


        switch (format)
        {
            case '1':
                print_ls(hidden, '\n', file_list);
                break;
            case 'l':
                print_ls(hidden, '\n', file_list);
                break;
            default:
                print_ls(hidden, '\t', file_list);
        }
        if (dir_node->next != NULL)
            putchar('\n');

        free_file_list(&file_list);
    }

    free_dir_list(&dir_list);
    closedir(dirp);
    return (0);
}


/**
 * print_ls - print contents in the default ls format, i.e. columns
 *
 * @hidden: parameter denoting the option for revealing hidden files
 * @format: printing format parameter
 * @dirp: pointer to the directory data
 *
 * Return: 0 for success, 1 for failure
 */
int print_ls(char hidden, char format, file_list_t *file_list)
{
    file_list_t *file_node;

    for (file_node = file_list; file_node != NULL; file_node = file_node->next)
    {
        if (hidden == 'a')
        {
            printf("%s", file_list->file);
            if (file_list->next != NULL)
                putchar(format);
        }
        else if (hidden == 'A')
        {
            if (strcmp(file_list->file, ".") != 0 &&
                strcmp(file_list->file, "..") != 0)
            {
                printf("%s", file_list->file);
                if (file_list->next != NULL)
                    putchar(format);
            }
        }
        else
        {
            if (file_list->file[0] != '.')
            {
                printf("%s", file_list->file); // (line 139)
                if (file_list->next != NULL)
                    putchar(format);
            }
        }
    }
    if (format == '\t')
        printf("\n");

    return (0);
}

add_file_list():

/**
 * add_file_list - add a new node at the start of a file_list_t linked list
 *
 * @head: start of linked list
 * @file: file data to add to node
 *
 * Return: address of new node; NULL if failure
 */
file_list_t *add_file_list(file_list_t **head, const char file[256])
{
    file_list_t *node;

    node = malloc(sizeof(file_list_t));
    if (node == NULL)
        return (NULL);
    strcpy(node->file, file);
    node->next = *head;
    node->prev = NULL;
    *head = node;
    return (node);
}

I'm thinking about trying this out with an array of pointers instead, but I don't want to throw away my code before getting some insight. Am I not inputting the data into the node correctly? If so, how would I do that?

HoldenGs
  • 87
  • 2
  • 8
  • 2
    Dangerous nonsense: `memset(dir, 0, strlen(dir));` And another one: `perror(strncat(error_message, dir_node->dir, max_src_bytes));` – wildplasser Jan 25 '18 at 00:08
  • `append_file_list` prepends. – ikegami Jan 25 '18 at 00:09
  • `append_file_list` doesn't change `head->prev` (if you want to continue prepending) or `head->next` (if you switch to appending). – ikegami Jan 25 '18 at 00:11
  • 1
    `strcpy(node->file, file);` is dangerous (if `node->file` is a char array) or wrong (if `node->file` is a pointer). – ikegami Jan 25 '18 at 00:11
  • @wildplasser it fixed an issue I had when printing out multiple directories. If I did `ls test/ my_dir/` It would print out `.my_dir` and `.test/` instead of just `my_dir`. – HoldenGs Jan 25 '18 at 00:12
  • I know I have the wrong name, @ikegami. I'm fine with it for now. What would you recommend I do for the char array instead? – HoldenGs Jan 25 '18 at 00:13
  • `strncpy` or length check. – ikegami Jan 25 '18 at 00:14
  • BTW:the code looks *reasonable*, except for the string handling. And: you dont need `()` in `return expression;` return is *not* a function. – wildplasser Jan 25 '18 at 00:17
  • Be aware of how you build pathnames with `readdir()` data — see [`stat()` error ENOENT with `readdir()`](https://stackoverflow.com/questions/5125919/). I've not checked to see if this is part of your problems — the comments suggest you've got other issues to deal with first. However, look there for advice if your memory management is clean but you still get 'no such file or directory' errors. – Jonathan Leffler Jan 25 '18 at 02:03
  • In Linux, and generally on all POSIXy systems, this approach is a dead end. Really. Use [`nftw()`](http://man7.org/linux/man-pages/man3/nftw.3.html), [`glob()`](http://man7.org/linux/man-pages/man3/glob.3.html), or [`wordexp()`](http://man7.org/linux/man-pages/man3/wordexp.3.html) instead; they are already in your (POSIX) C library. – Nominal Animal Jan 25 '18 at 03:34

1 Answers1

0

this is wrong, just as valgrind says

   file_head = file_list; <<<< file_list is not initlaized, file_head = junk
    while ((read = readdir(dirp)) != NULL)
    {
        printf("read: %s\n", read->d_name);
        append_file_list(&file_list, read->d_name);
        printf("file_list: %s\n", file_list->file);
    }
    printf("file_head: %s\n", file_head->file); <<<<<= (line 78) file_head = junk
pm100
  • 48,078
  • 23
  • 82
  • 145