19
19
#include < iostream>
20
20
21
21
// + standard includes
22
- #include < fcntl.h> // _O_BINARY in FileIo::FileIo
23
- #include < sys/stat.h> // for stat, chmod
22
+ #include < fcntl.h> // _O_BINARY in FileIo::FileIo
24
23
25
24
#if __has_include(<sys/mman.h>)
26
25
#include < sys/mman.h> // for mmap and munmap
37
36
#endif
38
37
39
38
#ifdef _WIN32
40
- using mode_t = unsigned short ;
41
39
#include < io.h>
42
40
#include < windows.h>
43
41
#endif
@@ -101,8 +99,8 @@ class FileIo::Impl {
101
99
// TYPES
102
100
// ! Simple struct stat wrapper for internal use
103
101
struct StructStat {
104
- mode_t st_mode{0 }; // !< Permissions
105
- off_t st_size{0 }; // !< Size
102
+ fs::perms st_mode{}; // !< Permissions
103
+ std:: uintmax_t st_size{}; // !< Size
106
104
};
107
105
// #endif
108
106
// METHODS
@@ -181,13 +179,13 @@ int FileIo::Impl::switchMode(OpMode opMode) {
181
179
} // FileIo::Impl::switchMode
182
180
183
181
int FileIo::Impl::stat (StructStat& buf) const {
184
- struct stat st;
185
- auto ret = ::stat (path_.c_str (), &st);
186
- if (ret == 0 ) {
187
- buf.st_size = st.st_size ;
188
- buf.st_mode = st.st_mode ;
182
+ try {
183
+ buf.st_size = fs::file_size (path_);
184
+ buf.st_mode = fs::status (path_).permissions ();
185
+ return 0 ;
186
+ } catch (const fs::filesystem_error&) {
187
+ return -1 ;
189
188
}
190
- return ret;
191
189
} // FileIo::Impl::stat
192
190
193
191
FileIo::FileIo (const std::string& path) : p_(std::make_unique<Impl>(path)) {
@@ -356,8 +354,8 @@ void FileIo::transfer(BasicIo& src) {
356
354
close ();
357
355
358
356
bool statOk = true ;
359
- mode_t origStMode = 0 ;
360
- auto pf = path (). c_str () ;
357
+ fs::perms origStMode = {} ;
358
+ auto pf = path ();
361
359
362
360
Impl::StructStat buf1;
363
361
if (p_->stat (buf1) == -1 ) {
@@ -372,14 +370,15 @@ void FileIo::transfer(BasicIo& src) {
372
370
// that file has been opened with FILE_SHARE_DELETE by another process,
373
371
// like a virus scanner or disk indexer
374
372
// (see also http://stackoverflow.com/a/11023068)
375
- auto ret = ReplaceFileA (pf, fileIo->path ().c_str (), nullptr , REPLACEFILE_IGNORE_MERGE_ERRORS, nullptr , nullptr );
373
+ auto ret =
374
+ ReplaceFileA (pf.c_str (), fileIo->path ().c_str (), nullptr , REPLACEFILE_IGNORE_MERGE_ERRORS, nullptr , nullptr );
376
375
if (ret == 0 ) {
377
376
if (GetLastError () != ERROR_FILE_NOT_FOUND)
378
377
throw Error (ErrorCode::kerFileRenameFailed, fileIo->path (), pf, strError ());
379
378
fs::rename (fileIo->path (), pf);
380
379
fs::remove (fileIo->path ());
381
380
} else {
382
- if (fileExists (pf) && ::remove (pf) != 0 )
381
+ if (fileExists (pf) && fs ::remove (pf) != 0 )
383
382
throw Error (ErrorCode::kerCallFailed, pf, strError (), " fs::remove" );
384
383
fs::rename (fileIo->path (), pf);
385
384
fs::remove (fileIo->path ());
@@ -392,15 +391,10 @@ void FileIo::transfer(BasicIo& src) {
392
391
fs::remove (fileIo->path ());
393
392
#endif
394
393
// Check permissions of new file
395
- struct stat buf2;
396
- if (statOk && ::stat (pf, &buf2) == -1 ) {
397
- statOk = false ;
398
- #ifndef SUPPRESS_WARNINGS
399
- EXV_WARNING << Error (ErrorCode::kerCallFailed, pf, strError (), " ::stat" ) << " \n " ;
400
- #endif
401
- }
394
+ auto newStMode = fs::status (pf).permissions ();
402
395
// Set original file permissions
403
- if (statOk && origStMode != buf2.st_mode && ::chmod (pf, origStMode) == -1 ) {
396
+ if (statOk && origStMode != newStMode) {
397
+ fs::permissions (pf, origStMode);
404
398
#ifndef SUPPRESS_WARNINGS
405
399
EXV_WARNING << Error (ErrorCode::kerCallFailed, pf, strError (), " ::chmod" ) << " \n " ;
406
400
#endif
@@ -1718,11 +1712,7 @@ DataBuf readFile(const std::string& path) {
1718
1712
if (file.open (" rb" ) != 0 ) {
1719
1713
throw Error (ErrorCode::kerFileOpenFailed, path, " rb" , strError ());
1720
1714
}
1721
- struct stat st;
1722
- if (0 != ::stat (path.c_str (), &st)) {
1723
- throw Error (ErrorCode::kerCallFailed, path, strError (), " ::stat" );
1724
- }
1725
- DataBuf buf (st.st_size );
1715
+ DataBuf buf (fs::file_size (path));
1726
1716
if (file.read (buf.data (), buf.size ()) != buf.size ()) {
1727
1717
throw Error (ErrorCode::kerCallFailed, path, strError (), " FileIo::read" );
1728
1718
}
0 commit comments