diff --git a/interface/wx/file.h b/interface/wx/file.h index 78fb12aa3c..4e354185a0 100644 --- a/interface/wx/file.h +++ b/interface/wx/file.h @@ -95,11 +95,14 @@ public: /** Returns the length of the file. - This method may return ::wxInvalidOffset if the length couldn't be - determined or 0 even for non-empty files if the file is not seekable. + Returns ::wxInvalidOffset if the length couldn't be determined. - In general, the only way to determine if the file for which this function - returns 0 is really empty or not is to try reading from it. + Please also note that there is @e no guarantee that reading that many + bytes from the file will always succeed. While this is true for regular + files (unless the file size has been changed by another process in + between Length() and Read() calls), some special files, such as most + files under @c /sys or @c /proc directories under Linux, don't actually + contain as much data as their size indicates. */ wxFileOffset Length() const; diff --git a/src/common/file.cpp b/src/common/file.cpp index 84cf9f78fc..9446bb32d9 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -474,21 +474,6 @@ wxFileOffset wxFile::Length() const { wxASSERT( IsOpened() ); - // we use a special method for Linux systems where files in sysfs (i.e. - // those under /sys typically) return length of 4096 bytes even when - // they're much smaller -- this is a problem as it results in errors later - // when we try reading 4KB from them -#ifdef __LINUX__ - struct stat st; - if ( fstat(m_fd, &st) == 0 ) - { - // returning 0 for the special files indicates to the caller that they - // are not seekable - return st.st_blocks ? st.st_size : 0; - } - //else: failed to stat, try the normal method -#endif // __LINUX__ - wxFileOffset iRc = Tell(); if ( iRc != wxInvalidOffset ) { wxFileOffset iLen = const_cast(this)->SeekEnd(); diff --git a/tests/file/filetest.cpp b/tests/file/filetest.cpp index faeed69dbf..f1876daf94 100644 --- a/tests/file/filetest.cpp +++ b/tests/file/filetest.cpp @@ -144,6 +144,10 @@ void FileTestCase::TempFile() // Check that GetSize() works correctly for special files. TEST_CASE("wxFile::Special", "[file][linux][special-file]") { + // We can't test /proc/kcore here, unlike in the similar + // wxFileName::GetSize() test, as wxFile must be able to open it (at least + // for reading) and usually we don't have the permissions to do it. + // This file is not seekable and has 0 size, but can still be read. wxFile fileProc("/proc/diskstats"); CHECK( fileProc.IsOpened() ); @@ -155,6 +159,7 @@ TEST_CASE("wxFile::Special", "[file][linux][special-file]") // All files in /sys seem to have size of 4KiB currently, even if they // don't have that much data in them. wxFile fileSys("/sys/power/state"); + CHECK( fileSys.Length() == 4096 ); CHECK( fileSys.IsOpened() ); CHECK( fileSys.ReadAll(&s) ); CHECK( !s.empty() ); diff --git a/tests/filename/filenametest.cpp b/tests/filename/filenametest.cpp index 739194323a..762061813c 100644 --- a/tests/filename/filenametest.cpp +++ b/tests/filename/filenametest.cpp @@ -1049,3 +1049,18 @@ void FileNameTestCase::TestShortcuts() } #endif // __WINDOWS__ + +#ifdef __LINUX__ + +// Check that GetSize() works correctly for special files. +TEST_CASE("wxFileName::GetSizeSpecial", "[filename][linux][special-file]") +{ + wxULongLong size = wxFileName::GetSize("/proc/kcore"); + INFO( "size of /proc/kcore=" << size ); + CHECK( size > 0 ); + + // All files in /sys seem to have size of 4KiB currently. + CHECK( wxFileName::GetSize("/sys/power/state") == 4096 ); +} + +#endif // __LINUX__