Reading directories using readdir_r

Guillermo Gruschka picture Guillermo Gruschka · Jul 17, 2012 · Viewed 9.6k times · Source

I've been checking and fighting with this procedure without success for quite a while, hope you can help me out.

The idea is to read the directory stored in c_Localpath and copy the read dirs into c_namesLocal to return them.

Am I doing something wrong in my implementation? The program breaks on the strcpy, and I have no clue why.

DIR* ptr_dir = opendir(c_Localpath);

char** c_namesLocal = calloc(1, 256);

    size_t numElements = 0;
    int returnCode =0;
    struct dirent ptr_PrevDirEntry;
    struct dirent* ptr_DirEntry = NULL;
    returnCode = readdir_r(ptr_dir, &ptr_PrevDirEntry,
            &ptr_DirEntry);

    while ((returnCode ==0) && (ptr_DirEntry != NULL)) {
        char* name = c_namesLocal[numElements];
        strcpy(name, ptr_DirEntry->d_name);
        ptr_PrevDirEntry = *ptr_DirEntry;
        returnCode = readdir_r(ptr_dir, &ptr_PrevDirEntry,
                &ptr_DirEntry);
        numElements++;
        c_namesLocal = realloc(c_namesLocal, 256 * numElements);
    }

Answer

Rohit picture Rohit · Nov 27, 2014

Sorry for replying after 2 years. But I wanted to help others who would like to know the answer. I have worked on the implementation of readdir_r and thus I have modified your code to make it work. I cannot say the codes as a whole would work but, it is definite that you could get the next file entry in the indicated directory you mentioned. And thus you could save those entries into other var and could do whatever you would like to.

Please see below.

DIR* ptr_dir = opendir(c_Localpath);
size_t numElements = 0;
int returnCode =0;
struct dirent *ptr_PrevDirEntry = NULL;
struct dirent *ptr_DirEntry = NULL;
int len_entry;
char *c_namesLocal = NULL;

len_entry = offsetof(struct dirent, d_name) + fpathconf(dirfd(ptr_dir), _PC_NAME_MAX) + 1;
ptr_PrevDirEntry = malloc(len_entry);

if(!ptr_PrevDirEntry)
        exit(0);

for(;;){
        readdir_r(ptr_dir, ptr_PrevDirEntry, &ptr_DirEntry);
        if(!ptr_DirEntry)
            break;
        else
        {
                 if((strcmp(ptr_DirEntry->d_name, ".") != 0) && (strcmp(ptr_DirEntry->d_name, "..") != 0)) // skip "." and ".." file listings
                 {
                    //Perform copying or do whatever you want with the file entry read from the dir "c_Localpath"
                    //Increase numElements to 1 and keep on increasing by 1 on every iteration
                    numElements++;
                    //realloc everytime you find next entry
                    c_namesLocal = realloc(c_namesLocal, 256 * numElements);
                    //copy the next file name in the c_namesLocal[0], c_namesLocal[1] and so on.
                    strcpy(c_namesLocal[numElements - 1], ptr_DirEntry->d_name);
                 }
        }
 }

 //free "ptr_PrevDirEntry" before returning and take care of "c_namesLocal" as well.

The codes above are self-explanatory. I hope it helps you. Cheers :)