Jin K
Jin K

Reputation: 11

Recursively counting files and all directories given the directory

I've been working on this project and I'm stuck on one of the line in this code.

This basically counts files and number of directories recursively through the directories using C++ in the UNIX environment, but whenever I do the recursive call it has an error saying:

Segmentation fault (core dumped)

I thought it was because I didn't check the "." and ".." but it wasn't it.

Is there anything wrong with the recursive call?

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

using namespace std;


void cntFile(string it, int &reg, int &der, size_t &size)
{
    DIR * dirp;
    struct dirent *entry;
    struct stat file_stats;

    dirp = opendir(it.c_str());
    while ((entry = readdir(dirp)) != NULL)
    {
        if (entry->d_type == DT_REG)
        {
            reg++;
            stat(getcwd(entry->d_name,sizeof(entry->d_name)), &file_stats);
            size += (unsigned int) file_stats.st_size;

        }
        else if (entry->d_type == DT_DIR)
        {  

           if(string(entry->d_name) != ".." | string(entry->d_name) != ".")
            {
                string temp;
                temp.append(it + entry->d_name + "/");
                cntFile(temp, reg, der, size);
            }
           der++;
        }
    }
    closedir(dirp); 
}

int main (void)
{
    int reg = 0;
    int der = 0;
    size_t size = 0;
    string it = "/usr/share/";
    cntFile(it, reg, der, size);
    printf("The total number of directories in directory is %d \n", reg);
    printf("The total number of files in directory is %d \n", der);
    printf("The total number of bytes occupied by all files in directory is %zu\n", size);
    return 0;
}

Upvotes: 1

Views: 265

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409356

There is one major problem in how you use readdir and the structure it returns a pointer to.

From the reference linked to above:

The application shall not modify the structure to which the return value of readdir() points, nor any storage areas pointed to by pointers within the structure.

And yet that's exactly what you're doing with the getcwd call, modify the contents of the structure member d_name.

If you want to modify the contents of the name in d_name you need to create your own local copy and use that.

Upvotes: 2

Related Questions