0

I've been working on this code for a while and I can not figure out the problem. The idea is to print out all directories and sub directories from the given directory (hard coded for testing purposes). However, I keep getting a segmentation fault.

#include <stdio.h>
#include <dirent.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

struct item
{
    char location[256];
    int level;
    int order;
    bool isExpanded;
    struct item *next;
};

struct item *headNode = NULL; 
struct item *currentNode = NULL;
struct item *loopNode = NULL;
static int currentLevel = 1;
static int currentOrder = 1;
bool finished = false;
char currentLocation[256];

void addNode(char location[256])
{
    struct item *ptr = (struct item*)malloc(sizeof(struct item));
    ptr->level = currentLevel;
    ptr->order = currentOrder;
    ptr->isExpanded = false;
    int x;
    for(x = 0; x < strlen(location); x++)
        ptr->location[x] = location[x];

    ptr->location[x] = '\0';
    ptr->next = NULL;

    currentNode->next = ptr;
    currentNode = ptr;
} 

int main(int argc, char *argv[])
{
    struct dirent *pDirent;
    DIR *pDir;
    argv[1] = "/home/collin/Documents";
    char temp[256];

    pDir = opendir (argv[1]);
    if (pDir == NULL) 
    {
        printf ("Cannot open directory '%s'\n", argv[1]);
        return 1;
    }
    closedir (pDir);

    headNode = (struct item*)malloc(sizeof(struct item));
    headNode->level = currentLevel;
    headNode->order = currentOrder;
    headNode->isExpanded = false;
    int x;
    for(x = 0; x < strlen(argv[1]); x++)
    {
        headNode->location[x] = argv[1][x];
        currentLocation[x] = argv[1][x];
    }

    headNode->location[x] = '\0';
    currentLocation[x] = '\0';
    headNode->next = NULL;

    currentNode = headNode;

    while(!finished)
    {
        finished = true;
        loopNode = headNode;
        currentLevel++;
        currentOrder = 1;
        while(loopNode != NULL)
        {
            if(!loopNode->isExpanded)
            {
                pDir = opendir (loopNode->location);
                for (x = 0; x < strlen(loopNode->location); x++)
                {
                    currentLocation[x] = loopNode->location[x];
                }
                currentLocation[x] = '\0';

                while ((pDirent = readdir(pDir)) != NULL) 
                {
                    finished = false;
                    if(!(!strcmp(pDirent->d_name, ".")||!strcmp(pDirent->d_name, "..")))
                    {
                        sprintf(temp, "%s/%s", currentLocation, pDirent->d_name);
                        addNode(temp);
                        currentOrder++;
                    }
                }
                closedir (pDir);
                loopNode->isExpanded = true;
            }
            loopNode = loopNode->next;
        }
    }

    currentNode = headNode;
    while (currentNode != NULL)
    {
        printf ("%d:%d:%s\n", currentNode->level, currentNode->order, currentNode->location);
        currentNode = currentNode->next;
    }

    return 0;
}
silastk
  • 21
  • 1
  • 2
  • 6
    Build the program with debug information (the `-g` flag to gcc) and run it in a debugger. The debugger will stop when the crash happens, and let you examine the function call stack, as well as let you walk up it. You can also examine the values of variables. If you can't figure it out by yourself, then at least edit your question to include the call stack when the crash happens. – Some programmer dude Sep 24 '13 at 07:57
  • 1
    By the way, why do you do manual copying of `argv[1]` into e.g. `currentLocation`? Why not use `strcpy`? You do this on more places too. – Some programmer dude Sep 24 '13 at 07:59
  • 1
    Also: [do not cast the result of malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) ! – Paul R Sep 24 '13 at 08:19
  • @JoachimPileborg I've tried running it in a debugger plugin in Geany, but it just crashes the entire program. This could easily be due to my lack of experience in linux in general. – silastk Sep 24 '13 at 15:53

1 Answers1

1

You're not checking that opendir's parameter is a directory, and trying to call it on files too. Either check opendir return value, or check that file you requesting to open is actually a directory, or - even better - both.

keltar
  • 17,711
  • 2
  • 37
  • 42
  • Yep, checking to see if pDir was NULL before running the readdir fixed the problem. Thanks. – silastk Sep 24 '13 at 16:18
  • @silastk the whole point is - learn to use debugger. It took less then a minute for me to just copy your code, compile, run in debugger and pinpoint a problem. You really should do the same at least for educational purpose. – keltar Sep 25 '13 at 03:02