Verified Commit 97f26a22 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

Add OpenDir class

In order to support directories functionalities
opendir,readdir,closedir,etc.. the OpenDir class has been introduced.
This is a new specialization of the OpenFile class so that OpenDir
object can be stored in the open_file_map along with regular file.
parent 4314bebe
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line

#ifndef IFS_OPEN_DIR_HPP
#define IFS_OPEN_DIR_HPP

#include <string>
#include <vector>

#include <dirent.h>

#include <preload/open_file_map.hpp>


class OpenDir: public OpenFile {
    private:

        class DirEntry {
            public:
                std::string name;
                file_type type;

                DirEntry(const std::string& name, const file_type type);
        };

        std::vector<DirEntry> entries;
        struct dirent dirent_;
        bool is_dirent_valid;

        void update_dirent(unsigned int pos);


    public:
        OpenDir(const std::string& path);
        void add(const std::string& name, const file_type& type);
        struct dirent * readdir();
};


#endif //IFS_OPEN_DIR_HPP
+6 −1
Original line number Diff line number Diff line
@@ -16,8 +16,13 @@ enum class OpenFile_flags {
    flag_count // this is purely used as a size variable of this enum class
};

enum file_type {
    regular,
    directory
};

class OpenFile {
private:
protected:
    std::string path_;
    std::array<bool, static_cast<int>(OpenFile_flags::flag_count)> flags_ = {false};
    off64_t pos_;
+2 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ set(PRELOAD_SRC
    intcp_functions.cpp
    margo_ipc.cpp
    open_file_map.cpp
    open_dir.cpp
    passthrough.cpp
    preload.cpp
    preload_util.cpp
@@ -27,6 +28,7 @@ set(PRELOAD_HEADERS
    ../../include/preload/adafs_functions.hpp
    ../../include/preload/margo_ipc.hpp
    ../../include/preload/open_file_map.hpp
    ../../include/preload/open_dir.hpp
    ../../include/preload/passthrough.hpp
    ../../include/preload/preload.hpp
    ../../include/preload/preload_util.hpp
+52 −0
Original line number Diff line number Diff line
#include <preload/open_dir.hpp>
#include <stdexcept>
#include <cstring>
#include <cassert>


OpenDir::DirEntry::DirEntry(const std::string& name, const file_type type):
    name(name), type(type) {
}


OpenDir::OpenDir(const std::string& path): OpenFile(path, 0){
    pos_ = 0;
    is_dirent_valid = false;
}


void OpenDir::add(const std::string& name, const file_type& type){
    entries.push_back(DirEntry(name, type));
}

void OpenDir::update_dirent(unsigned int pos){
    DirEntry entry = entries.at(pos);
    std::string entry_absolute_path = path_ + "/" + entry.name;
    dirent_.d_ino = std::hash<std::string>()(entry_absolute_path);
    dirent_.d_off = pos_;
    dirent_.d_type = ((entry.type == regular)? DT_REG : DT_DIR);
    assert(sizeof(dirent_.d_name) >= strlen(entry.name.c_str()));
    strcpy(dirent_.d_name, entry.name.c_str());
    dirent_.d_reclen = sizeof(dirent_);
}

struct dirent * OpenDir::readdir(){
    unsigned int next_pos;

    if(!is_dirent_valid){
        next_pos = 0;
    }else{
        next_pos = pos_ + 1;
    }

    //We reached the end of entries list
    if( next_pos >= entries.size()){
        is_dirent_valid = false;
        return NULL;
    }

    update_dirent(next_pos);
    pos_ = next_pos;
    is_dirent_valid = true;
    return &dirent_;
}