Narek Margaryan
Narek Margaryan

Reputation: 334

Segmentation fault, listing contents of a directory

I am getting segmentation fault upon the end of a while loop(I am not sure if the error appears after termination or before). I have checked that dirlist_next_entry successfully returns DIRLIST_END after end of directory stream is reached. I don't understand what causes the fault as the loop should successfully terminate after end of stream is reached

#include "DirEntry.h"
#include <cstdio>

int main(int argc, char* argv[]){
    if(argc != 2){
        printf("Directory not specified\n");
        return -1;
    }
    DirListError error;
    DirEntry result;
    handle hfile = dirlist_start_find(argv[1], &error);
    while( dirlist_next_entry(hfile, &result) != DIRLIST_END){
        printf("%s  %lld\n", result.entry, result.size);
    }
    dirlist_end_find(hfile);

}

Here is the definition of dirlist_next_entry:

DirListError dirlist_next_entry(handle h, DirEntry* result){
    DIR* dirp = (DIR*)h; 
    dirent* dr;
    if((dr = readdir(dirp)) == NULL){
        return DIRLIST_END;
    }

        strcpy(result->entry, dr->d_name);
    if(dr->d_type == DT_DIR){
        result->is_directory = 1;
    }
    else if(dr->d_type == DT_REG){
        result->is_directory = 0;
        struct stat* buf;
        stat(result->entry, buf);
        result->size = buf->st_size;
    } 

    return DIRLIST_OK;  
}

Direntry.h is just a header with a couple of declarations:

#ifndef  DIRENTRY_H
#define DIRENTRY_H

const int MAX_PATH_LENGTH = 1024;
typedef void* handle;

struct DirEntry{
    char entry[MAX_PATH_LENGTH + 1];
    int is_directory;
    long long size;
};

enum DirListError{
    DIRLIST_OK,
    DIRECTORY_NOT_FOUND,
    INCORRECT_DIRECTORY_NAME,
    DIRLIST_END,
};

handle dirlist_start_find(const char* dir, DirListError* error);
DirListError dirlist_next_entry(handle h, DirEntry* result);
void dirlist_end_find(handle h);
#endif

Upvotes: 1

Views: 312

Answers (2)

R Samuel Klatchko
R Samuel Klatchko

Reputation: 76611

This is most likely overwriting random memory:

struct stat* buf;
stat(result->entry, buf);

It should be:

struct stat buf;
stat(result->entry, &buf);

Upvotes: 2

rondoisthebest
rondoisthebest

Reputation: 105

I believe that the d_name field of dirent* is not null terminated. So strcpy() on this may lead to a segmentation fault later on. If this is the case you should use strncpy()

Upvotes: 2

Related Questions