Search code examples
csubdirectorydirectory-traversal

Directory traversing in C


I tried to search for this question but couldn't find satisfying answer. So here's my question:

I am traversing through directories with following variations of code:

I.

#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>

void traverseDirectory(char name[100]){
        DIR* dir;
        struct dirent *ent;
        struct stat states;

        dir = opendir(name);

        while((ent=readdir(dir)) != NULL){
                stat(ent->d_name,&states);
                if(!strcmp(".", ent->d_name) || !strcmp("..", ent->d_name)){
                        continue;
                }
                else{
                        printf("%s/%s\n",name,ent->d_name);
                        if(S_ISDIR(states.st_mode)){
                                strcat(name,"/");
                                strcat(name,ent->d_name);
                                traverseDirectory(name);
                        }
                }
        }

        closedir(dir);
}

int main(){
        char path[100];
        printf("Enter the path:\n");
        scanf("%s",&path);
        traverseDirectory(path);
}

This one traverses through sub-directories but gives segmentation fault after traversing through first sub-directory & printing its files.

Output is:

Enter the path:
/home/harshad/dump

/home/harshad/dump/TraverseDirectory.c

/home/harshad/dump/temp

/home/harshad/dump/temp/temptest.txt
Segmentation fault

II.

#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>

void traverseDirectory(char name[100]){
        DIR* dir;
        struct dirent *ent;
        struct stat states;

        dir = opendir(name);

        while((ent=readdir(dir)) != NULL){
                stat(ent->d_name,&states);
                if(!strcmp(".", ent->d_name) || !strcmp("..", ent->d_name)){
                        continue;
                }
                else{
                        printf("%s/%s\n",name,ent->d_name);
                        if(S_ISDIR(ent->d_type & DT_DIR)){
                                strcat(name,"/");
                                strcat(name,ent->d_name);
                                traverseDirectory(name);
                        }
                }
        }

        closedir(dir);
}

int main(){
        char path[100];
        printf("Enter the path:\n");
        scanf("%s",&path);
        traverseDirectory(path);
}

This one prints all the files & sub-directories in given directory but doesn't traverse in sub-directories. It's output is:

Enter the path:
/home/harshad/dump

/home/harshad/dump/TraverseDirectory.c

/home/harshad/dump/temp

/home/harshad/dump/TraverseDirectory1.out

/home/harshad/dump/dump

/home/harshad/dump/test.txt

/home/harshad/dump/SortMarks.c

/home/harshad/dump/TraverseDirectory.out

/home/harshad/dump/TraverseDirectoryTemp.out

/home/harshad/dump/TraverseDirectory1.c

/home/harshad/dump/TraverseDirectoryTemp.c

/home/harshad/dump/FindEven.c

Here dump & temp are sub-directories each of which contains some files. First I thought because of user permissions it might not be able to traverse in sub-directories (as they are created & owned by root) but as you can see in 1st program's output that is not the case. So I am not able to figure out problems with both the programs. P.S.: In outputs after first two lines program prints directories & files.


Solution

  • You should really check for error in opendir(). If it fails it will return NULL, and then the next readdir() will seg-fault.

    This may be enough:

    dir = opendir(name);
    if (!dir)
    {
        perror(name);
        return;
    }