replace stat with std::filesystem

Signed-off-by: Rosen Penev <rosenp@gmail.com>
main
Rosen Penev 2 years ago
parent 3b15b6f9fb
commit 6ea6e2cb13

@ -20,8 +20,6 @@ namespace fs = std::experimental::filesystem;
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
char* realpath(const char* file, char* path);
#define lstat stat
#if _MSC_VER < 1400 #if _MSC_VER < 1400
#define strcpy_s(d, l, s) strcpy(d, s) #define strcpy_s(d, l, s) strcpy(d, s)
#define strcat_s(d, l, s) strcat(d, s) #define strcat_s(d, l, s) strcat(d, s)
@ -464,8 +462,6 @@ bool readDir(const char* path, Options& options) {
// print all the files and directories within directory // print all the files and directories within directory
while ((ent = readdir(dir)) != nullptr) { while ((ent = readdir(dir)) != nullptr) {
std::string pathName = makePath(path, ent->d_name); std::string pathName = makePath(path, ent->d_name);
struct stat buf;
lstat(path, &buf);
if (ent->d_name[0] != '.') { if (ent->d_name[0] != '.') {
// printf("reading %s => %s\n",ent->d_name,pathName.c_str()); // printf("reading %s => %s\n",ent->d_name,pathName.c_str());
if (getFileType(pathName, options) == typeImage) { if (getFileType(pathName, options) == typeImage) {

@ -19,8 +19,7 @@
#include <iostream> #include <iostream>
// + standard includes // + standard includes
#include <fcntl.h> // _O_BINARY in FileIo::FileIo #include <fcntl.h> // _O_BINARY in FileIo::FileIo
#include <sys/stat.h> // for stat, chmod
#if __has_include(<sys/mman.h>) #if __has_include(<sys/mman.h>)
#include <sys/mman.h> // for mmap and munmap #include <sys/mman.h> // for mmap and munmap
@ -37,7 +36,6 @@
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
using mode_t = unsigned short;
#include <io.h> #include <io.h>
#include <windows.h> #include <windows.h>
#endif #endif
@ -101,8 +99,8 @@ class FileIo::Impl {
// TYPES // TYPES
//! Simple struct stat wrapper for internal use //! Simple struct stat wrapper for internal use
struct StructStat { struct StructStat {
mode_t st_mode{0}; //!< Permissions fs::perms st_mode{}; //!< Permissions
off_t st_size{0}; //!< Size std::uintmax_t st_size{}; //!< Size
}; };
// #endif // #endif
// METHODS // METHODS
@ -181,13 +179,13 @@ int FileIo::Impl::switchMode(OpMode opMode) {
} // FileIo::Impl::switchMode } // FileIo::Impl::switchMode
int FileIo::Impl::stat(StructStat& buf) const { int FileIo::Impl::stat(StructStat& buf) const {
struct stat st; try {
auto ret = ::stat(path_.c_str(), &st); buf.st_size = fs::file_size(path_);
if (ret == 0) { buf.st_mode = fs::status(path_).permissions();
buf.st_size = st.st_size; return 0;
buf.st_mode = st.st_mode; } catch (const fs::filesystem_error&) {
return -1;
} }
return ret;
} // FileIo::Impl::stat } // FileIo::Impl::stat
FileIo::FileIo(const std::string& path) : p_(std::make_unique<Impl>(path)) { FileIo::FileIo(const std::string& path) : p_(std::make_unique<Impl>(path)) {
@ -356,8 +354,8 @@ void FileIo::transfer(BasicIo& src) {
close(); close();
bool statOk = true; bool statOk = true;
mode_t origStMode = 0; fs::perms origStMode = {};
auto pf = path().c_str(); auto pf = path();
Impl::StructStat buf1; Impl::StructStat buf1;
if (p_->stat(buf1) == -1) { if (p_->stat(buf1) == -1) {
@ -372,14 +370,15 @@ void FileIo::transfer(BasicIo& src) {
// that file has been opened with FILE_SHARE_DELETE by another process, // that file has been opened with FILE_SHARE_DELETE by another process,
// like a virus scanner or disk indexer // like a virus scanner or disk indexer
// (see also http://stackoverflow.com/a/11023068) // (see also http://stackoverflow.com/a/11023068)
auto ret = ReplaceFileA(pf, fileIo->path().c_str(), nullptr, REPLACEFILE_IGNORE_MERGE_ERRORS, nullptr, nullptr); auto ret =
ReplaceFileA(pf.c_str(), fileIo->path().c_str(), nullptr, REPLACEFILE_IGNORE_MERGE_ERRORS, nullptr, nullptr);
if (ret == 0) { if (ret == 0) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) if (GetLastError() != ERROR_FILE_NOT_FOUND)
throw Error(ErrorCode::kerFileRenameFailed, fileIo->path(), pf, strError()); throw Error(ErrorCode::kerFileRenameFailed, fileIo->path(), pf, strError());
fs::rename(fileIo->path(), pf); fs::rename(fileIo->path(), pf);
fs::remove(fileIo->path()); fs::remove(fileIo->path());
} else { } else {
if (fileExists(pf) && ::remove(pf) != 0) if (fileExists(pf) && fs::remove(pf) != 0)
throw Error(ErrorCode::kerCallFailed, pf, strError(), "fs::remove"); throw Error(ErrorCode::kerCallFailed, pf, strError(), "fs::remove");
fs::rename(fileIo->path(), pf); fs::rename(fileIo->path(), pf);
fs::remove(fileIo->path()); fs::remove(fileIo->path());
@ -392,15 +391,10 @@ void FileIo::transfer(BasicIo& src) {
fs::remove(fileIo->path()); fs::remove(fileIo->path());
#endif #endif
// Check permissions of new file // Check permissions of new file
struct stat buf2; auto newStMode = fs::status(pf).permissions();
if (statOk && ::stat(pf, &buf2) == -1) {
statOk = false;
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << Error(ErrorCode::kerCallFailed, pf, strError(), "::stat") << "\n";
#endif
}
// Set original file permissions // Set original file permissions
if (statOk && origStMode != buf2.st_mode && ::chmod(pf, origStMode) == -1) { if (statOk && origStMode != newStMode) {
fs::permissions(pf, origStMode);
#ifndef SUPPRESS_WARNINGS #ifndef SUPPRESS_WARNINGS
EXV_WARNING << Error(ErrorCode::kerCallFailed, pf, strError(), "::chmod") << "\n"; EXV_WARNING << Error(ErrorCode::kerCallFailed, pf, strError(), "::chmod") << "\n";
#endif #endif
@ -1718,11 +1712,7 @@ DataBuf readFile(const std::string& path) {
if (file.open("rb") != 0) { if (file.open("rb") != 0) {
throw Error(ErrorCode::kerFileOpenFailed, path, "rb", strError()); throw Error(ErrorCode::kerFileOpenFailed, path, "rb", strError());
} }
struct stat st; DataBuf buf(fs::file_size(path));
if (0 != ::stat(path.c_str(), &st)) {
throw Error(ErrorCode::kerCallFailed, path, strError(), "::stat");
}
DataBuf buf(st.st_size);
if (file.read(buf.data(), buf.size()) != buf.size()) { if (file.read(buf.data(), buf.size()) != buf.size()) {
throw Error(ErrorCode::kerCallFailed, path, strError(), "FileIo::read"); throw Error(ErrorCode::kerCallFailed, path, strError(), "FileIo::read");
} }

@ -35,7 +35,7 @@ namespace fs = std::experimental::filesystem;
#endif #endif
#if __has_include(<unistd.h>) #if __has_include(<unistd.h>)
#include <unistd.h> // for stat() #include <unistd.h> // for getpid()
#endif #endif
#if defined(__FreeBSD__) #if defined(__FreeBSD__)

Loading…
Cancel
Save