Skip to content
Snippets Groups Projects
Commit aef76520 authored by Adrien Béraud's avatar Adrien Béraud Committed by Tristan Matthews
Browse files

fileutils: add readDirectory

Create an abstraction layer to access directory content

Change-Id: I551475db784c0348f19cfe1d674131382c68a90c
parent e245f932
Branches
Tags
No related merge requests found
......@@ -65,7 +65,6 @@
#include <unistd.h>
#include <pwd.h>
#include <dirent.h>
#include <algorithm>
#include <array>
......@@ -614,19 +613,10 @@ DHTAccount::loadNodes() const
std::vector<dht::Dht::ValuesExport>
DHTAccount::loadValues() const
{
struct dirent *entry;
DIR *dp = opendir(dataPath_.c_str());
if (!dp) {
SFL_ERR("Could not load values from %s", dataPath_.c_str());
return {};
}
std::vector<dht::Dht::ValuesExport> values;
while ((entry = readdir(dp))) {
const auto dircontent(fileutils::readDirectory(dataPath_));
for (const auto& fname : dircontent) {
try {
const std::string fname {entry->d_name};
if (fname == "." || fname == "..")
continue;
std::ifstream ifs(dataPath_+DIR_SEPARATOR_STR+fname, std::ifstream::in | std::ifstream::binary);
std::istreambuf_iterator<char> begin(ifs), end;
values.push_back({{fname}, std::vector<uint8_t>{begin, end}});
......@@ -635,8 +625,6 @@ DHTAccount::loadValues() const
continue;
}
}
closedir(dp);
return values;
}
......
......@@ -58,6 +58,7 @@
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <cstddef>
namespace fileutils {
// returns true if directory exists
......@@ -210,6 +211,55 @@ bool isDirectoryWritable(const std::string &directory)
return access(directory.c_str(), W_OK) == 0;
}
static size_t
dirent_buf_size(DIR * dirp)
{
long name_max;
#if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) && defined(_PC_NAME_MAX)
name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
if (name_max == -1)
#if defined(NAME_MAX)
name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
#else
return (size_t)(-1);
#endif
#else
#if defined(NAME_MAX)
name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
#else
#error "buffer size for readdir_r cannot be determined"
#endif
#endif
size_t name_end = (size_t) offsetof(struct dirent, d_name) + name_max + 1;
return name_end > sizeof(struct dirent) ? name_end : sizeof(struct dirent);
}
std::vector<std::string>
readDirectory(const std::string& dir)
{
DIR *dp = opendir(dir.c_str());
if (!dp) {
SFL_ERR("Could not open %s", dir.c_str());
return {};
}
size_t size = dirent_buf_size(dp);
if (size == -1)
return {};
std::vector<uint8_t> buf(size);
dirent* entry;
std::vector<std::string> files;
while (!readdir_r(dp, reinterpret_cast<dirent*>(buf.data()), &entry) && entry) {
const std::string fname {entry->d_name};
if (fname == "." || fname == "..")
continue;
files.push_back(std::move(fname));
}
closedir(dp);
return files;
}
FileHandle::FileHandle(const std::string &n) : fd(-1), name(n)
{}
......
......@@ -32,6 +32,7 @@
#define FILEUTILS_H_
#include <string>
#include <vector>
#define PROTECTED_GETENV(str) ({char *envvar_ = getenv((str)); \
envvar_ ? envvar_ : "";})
......@@ -56,6 +57,14 @@ namespace fileutils {
std::string get_ringtone_dir();
std::string expand_path(const std::string &path);
bool isDirectoryWritable(const std::string &directory);
/**
* Read content of the directory.
* The result is a list of full paths of files in the directory,
* without "." and "..".
*/
std::vector<std::string> readDirectory(const std::string &dir);
struct FileHandle {
int fd;
const std::string name;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment