0

I'm trying to create an iterative program that reads all the folders from a specific starting folder using GSList and C. I haven't managed to find what the flaw in my code is for now.

The problem I'm having is that it reads each folder and all of it's subfolders until in reaches one with more subfolders. After that it just repeats to open only one directory.

The running result is below: http://pastebin.com/jZMFBrxC

Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <limits.h>
#include <errno.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    GSList *list = NULL;
    list = g_slist_prepend(list, "/home/ravior/Documente");        /* Folder for searching */

    DIR *d;

    int index = 0;

    while((char *)g_slist_nth_data(list, 0) != NULL) {
        gchar *element = g_strdup((char *)g_slist_nth_data(list, 0));
        d = opendir(element);
        if(!d) {
            fprintf(stderr, "Couldn't open '%s' : %s\n", (char *)g_slist_nth_data(list, 0), strerror(errno));
            exit(EXIT_FAILURE);
        }

        printf("\n\nThe opened folder is: %s\n\n", (char *)g_slist_nth_data(list, 0));

        while(TRUE) {
            struct dirent *entry;
            const char *d_name;

            entry = readdir(d);
            if(!entry) {
                break;
            }

            d_name = entry->d_name;

            /* Some code here... */

            if(entry->d_type & DT_DIR && strcmp(d_name, "..") != 0 && strcmp(d_name, ".") != 0) {
                int path_length;
                static char path[PATH_MAX];

                path_length = snprintf(path, PATH_MAX, "%s/%s",element, d_name);
                if(path_length >= PATH_MAX) {
                    fprintf(stderr, "Path length has got too long.\n");
                    exit(EXIT_FAILURE);
                }

                printf("%s\n", path);
                list = g_slist_append(list, path);
                index++;
                printf("The appended element is: %s\n", (char *)g_slist_nth_data(list, index));
            }
        }

        if(closedir(d)){
            fprintf(stderr, "Couldn't close' '%s': %s\n",(char *)g_slist_nth_data(list, 0), strerror(errno));
        }

        list = g_slist_remove(list, (char *)g_slist_nth_data(list, 0));
        free(element);
        element = NULL;
        index--;
    }

    g_slist_free(list);

    return EXIT_SUCCESS;
}

Any help to solve this is more than appreciated. Also, if you have any other implementation for this problem using C, sharing it will be more than appreciated.

Ravior
  • 1
  • 2

1 Answers1

0

I've managed to figure it out eventually.

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <limits.h>
#include <errno.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    GSList *list = NULL;
    list = g_slist_prepend(list, "/home/ravior/Documente");        /* Folder for searching */

    DIR *d;

    int index = 0;

    while((char *)g_slist_nth_data(list, 0) != NULL) {

        gchar *element = g_strdup((char *)g_slist_nth_data(list, 0));
        d = opendir(element);
        if(!d) {
            fprintf(stderr, "Couldn't open '%s' : %s\n", element, strerror(errno));
            exit(EXIT_FAILURE);
        }

        printf("\n\nThe opened folder is: %s\n\n", element);

        while(TRUE) {
            struct dirent *entry;
            const char *d_name;

            entry = readdir(d);
            if(!entry) {
                break;
            }

            d_name = entry->d_name;

            /* Some code here... */

            if(entry->d_type & DT_DIR && strcmp(d_name, "..") != 0 && strcmp(d_name, ".") != 0) {
                int path_length;
                static char path[PATH_MAX];

                path_length = snprintf(path, PATH_MAX, "%s/%s",element, d_name);
                if(path_length >= PATH_MAX) {
                    fprintf(stderr, "Path length has got too long.\n");
                    exit(EXIT_FAILURE);
                }

                printf("%s\n", path);
                list = g_slist_append(list, strdup(path));
                index++;
                printf("The appended element is: %s\n", (char *)g_slist_nth_data(list, index));
            }
        }

        if(closedir(d)){
            fprintf(stderr, "Couldn't close' '%s': %s\n", element, strerror(errno));
        }

        list = g_slist_remove(list, (char *)g_slist_nth_data(list, 0));

        free(element);
        element = NULL;
        index--;
    }

    g_slist_free(list);

    return EXIT_SUCCESS;
}

I hope this piece of code will help someone in the future.

Ravior
  • 1
  • 2
  • What was the solution? It's unlikely to help someone if they have to compare each line of this to your previous code sample... – ptomato Aug 17 '13 at 16:07
  • The problem was with the appending to the list: `list = g_slist_append(list, strdup(path));` I needed to make a copy of the array path, not just appending it, because all it will do is appending the last element. Also, another 'flaw' of my thinking was when I was removing the element. `list = g_slist_remove(list, (char *)g_slist_nth_data(list, 0));` Using '`element`' instead of '`(char *)g_slist_nth_data(list, 0))`' won't work because element just holds a copy of that data. It won't remove the desired element. It just won't do anything. – Ravior Aug 18 '13 at 20:58