Remove st_blocks hack from wxFile::Length() under Linux

This reverts commit 41f6f17d01 ("return 0
(meaning the file is not seekable, as the docs now explain) instead of
4KB for the files in sysfs under Linux") as it seems to be wrong to
return a value different from what "ls -l" or "stat" return here and the
original problem was solved in a better way in the previous commit.

See #9965.

Closes #17818.
This commit is contained in:
Vadim Zeitlin 2017-12-15 17:19:09 +01:00
parent cc86de1416
commit a03ece4880
4 changed files with 27 additions and 19 deletions

View File

@ -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;

View File

@ -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<wxFile *>(this)->SeekEnd();

View File

@ -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() );

View File

@ -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__