mirror of
https://github.com/AGWA/git-crypt.git
synced 2025-12-25 20:34:15 -08:00
Use opendir/readdir instead of scandir
scandir is a relatively recent addition to POSIX and is not available on older versions of Mac OS X. opendir/readdir should be more portable.
This commit is contained in:
@@ -43,6 +43,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
||||
std::string System_error::message () const
|
||||
{
|
||||
@@ -310,25 +312,47 @@ int util_rename (const char* from, const char* to)
|
||||
return rename(from, to);
|
||||
}
|
||||
|
||||
static int dirfilter (const struct dirent* ent)
|
||||
static size_t sizeof_dirent_for (DIR* p)
|
||||
{
|
||||
// filter out . and ..
|
||||
return std::strcmp(ent->d_name, ".") != 0 && std::strcmp(ent->d_name, "..") != 0;
|
||||
long name_max = fpathconf(dirfd(p), _PC_NAME_MAX);
|
||||
if (name_max == -1) {
|
||||
#ifdef NAME_MAX
|
||||
name_max = NAME_MAX;
|
||||
#else
|
||||
name_max = 255;
|
||||
#endif
|
||||
}
|
||||
return offsetof(struct dirent, d_name) + name_max + 1; // final +1 is for d_name's null terminator
|
||||
}
|
||||
|
||||
std::vector<std::string> get_directory_contents (const char* path)
|
||||
{
|
||||
struct dirent** namelist;
|
||||
int n = scandir(path, &namelist, dirfilter, alphasort);
|
||||
if (n == -1) {
|
||||
throw System_error("scandir", path, errno);
|
||||
}
|
||||
std::vector<std::string> contents(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
contents[i] = namelist[i]->d_name;
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
std::vector<std::string> contents;
|
||||
|
||||
DIR* dir = opendir(path);
|
||||
if (!dir) {
|
||||
throw System_error("opendir", path, errno);
|
||||
}
|
||||
try {
|
||||
std::vector<unsigned char> buffer(sizeof_dirent_for(dir));
|
||||
struct dirent* dirent_buffer = reinterpret_cast<struct dirent*>(&buffer[0]);
|
||||
struct dirent* ent = NULL;
|
||||
int err = 0;
|
||||
while ((err = readdir_r(dir, dirent_buffer, &ent)) == 0 && ent != NULL) {
|
||||
if (std::strcmp(ent->d_name, ".") == 0 || std::strcmp(ent->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
contents.push_back(ent->d_name);
|
||||
}
|
||||
if (err != 0) {
|
||||
throw System_error("readdir_r", path, errno);
|
||||
}
|
||||
} catch (...) {
|
||||
closedir(dir);
|
||||
throw;
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
std::sort(contents.begin(), contents.end());
|
||||
return contents;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user