aboutsummaryrefslogtreecommitdiff
path: root/dep/cppformat/posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dep/cppformat/posix.cc')
-rw-r--r--dep/cppformat/posix.cc38
1 files changed, 24 insertions, 14 deletions
diff --git a/dep/cppformat/posix.cc b/dep/cppformat/posix.cc
index 4c086af6ab0..0efb5aff3d0 100644
--- a/dep/cppformat/posix.cc
+++ b/dep/cppformat/posix.cc
@@ -45,16 +45,17 @@
# define O_CREAT _O_CREAT
# define O_TRUNC _O_TRUNC
-#ifndef S_IRUSR
-# define S_IRUSR _S_IREAD
-#endif
+# ifndef S_IRUSR
+# define S_IRUSR _S_IREAD
+# endif
-#ifndef S_IWUSR
-# define S_IWUSR _S_IWRITE
-#endif
+# ifndef S_IWUSR
+# define S_IWUSR _S_IWRITE
+# endif
# ifdef __MINGW32__
# define _SH_DENYNO 0x40
+# undef fileno
# endif
#endif // _WIN32
@@ -97,8 +98,11 @@ void fmt::BufferedFile::close() {
throw SystemError(errno, "cannot close file");
}
+// A macro used to prevent expansion of fileno on broken versions of MinGW.
+#define FMT_ARGS
+
int fmt::BufferedFile::fileno() const {
- int fd = FMT_POSIX_CALL(fileno(file_));
+ int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
if (fd == -1)
throw SystemError(errno, "cannot get file descriptor");
return fd;
@@ -106,7 +110,7 @@ int fmt::BufferedFile::fileno() const {
fmt::File::File(fmt::StringRef path, int oflag) {
int mode = S_IRUSR | S_IWUSR;
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__MINGW32__)
fd_ = -1;
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
#else
@@ -136,13 +140,19 @@ void fmt::File::close() {
fmt::LongLong fmt::File::size() const {
#ifdef _WIN32
- LARGE_INTEGER filesize = {};
+ // Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
+ // is less than 0x0500 as is the case with some default MinGW builds.
+ // Both functions support large file sizes.
+ DWORD size_upper = 0;
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
- if (!FMT_SYSTEM(GetFileSizeEx(handle, &filesize)))
- throw WindowsError(GetLastError(), "cannot get file size");
- FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(filesize.QuadPart),
- "return type of File::size is not large enough");
- return filesize.QuadPart;
+ DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
+ if (size_lower == INVALID_FILE_SIZE) {
+ DWORD error = GetLastError();
+ if (error != NO_ERROR)
+ throw WindowsError(GetLastError(), "cannot get file size");
+ }
+ fmt::ULongLong size = size_upper;
+ return (size << sizeof(DWORD) * CHAR_BIT) | size_lower;
#else
typedef struct stat Stat;
Stat file_stat = Stat();