1

I've implemented a method as below:

long getSize(const char *d_name)
{
    struct stat buff {};

    // stat(const char* var) always returns -1
    int exists = stat(d_name, &buff);

    long totalSize = 0;

    // So totalSize never increases
    if (exists > -1)
        totalSize += buff.st_size;

    return totalSize;
} 

Also I have a structure:

struct Entity
{
    string name;
    string type;
    long size;
    string created_at;
    string modofied_at; // equivalence to "modified" phrase
    bool isHidden;
};

I want to iterate over files in a specific path and locate their data (size, name, etc) into a vector containing structures of each entity (file or dir). So I implemented this:

vector<Entity> getEntities(const char *path)
{
    vector<Entity> entities;

    DIR *dir;
    struct dirent *ent;

    /** if path exists **/
    if ((dir = opendir(path)) == nullptr)
    {
        /* could not open directory */
        perror("path_invalid");
        exit(1);
    }

    /** loop over entities till encounters nullptr **/
    while ((ent = readdir(dir)) != nullptr)
    {
        Entity entity;

        entity.name = ent->d_name;

        // This member is always 0
        entity.size = this->getSize(ent->d_name);

        entity.isHidden = this->isHidden(ent->d_name);
        entities.push_back(entity);
    }

    closedir(dir);
    return entities;
} 

The problem is that stat always returns -1. So Entity's size always will be assigned unexpectedly to 0.

underscore_d
  • 6,309
  • 3
  • 38
  • 64

1 Answers1

2
if ((dir = opendir(path)) == nullptr)

Let's say you opened the "/etc" directory here. Here, path will be "/etc".

The code then proceeds to loop through the directory. Let's say it finds the passwd file; that is you'll be working with "/etc/passwd", at the moment.

entity.size = this->getSize(ent->d_name);

d_name will be "passwd" here. That's the name of this file in that directory. Then, when you get down to business, your code does this:

int exists = stat(d_name, &buff);

This will, of course, fail and return -1. This attempts to stat() a file whose name is "passwd".

Of course, no such file exists. The file is "/etc/passwd".

You need to prepend the directory name to the file's name, to form a complete pathname. For debugging purposes, make sure that you print the pathname string before you stat() it, to verify that you prepended the directory name correctly.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Thanks I got the problem. I fixed it by concatenating d_name and it's location path. –  Apr 17 '18 at 12:40