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:
@@ -95,11 +95,14 @@ public:
|
|||||||
/**
|
/**
|
||||||
Returns the length of the file.
|
Returns the length of the file.
|
||||||
|
|
||||||
This method may return ::wxInvalidOffset if the length couldn't be
|
Returns ::wxInvalidOffset if the length couldn't be determined.
|
||||||
determined or 0 even for non-empty files if the file is not seekable.
|
|
||||||
|
|
||||||
In general, the only way to determine if the file for which this function
|
Please also note that there is @e no guarantee that reading that many
|
||||||
returns 0 is really empty or not is to try reading from it.
|
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;
|
wxFileOffset Length() const;
|
||||||
|
|
||||||
|
@@ -474,21 +474,6 @@ wxFileOffset wxFile::Length() const
|
|||||||
{
|
{
|
||||||
wxASSERT( IsOpened() );
|
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();
|
wxFileOffset iRc = Tell();
|
||||||
if ( iRc != wxInvalidOffset ) {
|
if ( iRc != wxInvalidOffset ) {
|
||||||
wxFileOffset iLen = const_cast<wxFile *>(this)->SeekEnd();
|
wxFileOffset iLen = const_cast<wxFile *>(this)->SeekEnd();
|
||||||
|
@@ -144,6 +144,10 @@ void FileTestCase::TempFile()
|
|||||||
// Check that GetSize() works correctly for special files.
|
// Check that GetSize() works correctly for special files.
|
||||||
TEST_CASE("wxFile::Special", "[file][linux][special-file]")
|
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.
|
// This file is not seekable and has 0 size, but can still be read.
|
||||||
wxFile fileProc("/proc/diskstats");
|
wxFile fileProc("/proc/diskstats");
|
||||||
CHECK( fileProc.IsOpened() );
|
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
|
// All files in /sys seem to have size of 4KiB currently, even if they
|
||||||
// don't have that much data in them.
|
// don't have that much data in them.
|
||||||
wxFile fileSys("/sys/power/state");
|
wxFile fileSys("/sys/power/state");
|
||||||
|
CHECK( fileSys.Length() == 4096 );
|
||||||
CHECK( fileSys.IsOpened() );
|
CHECK( fileSys.IsOpened() );
|
||||||
CHECK( fileSys.ReadAll(&s) );
|
CHECK( fileSys.ReadAll(&s) );
|
||||||
CHECK( !s.empty() );
|
CHECK( !s.empty() );
|
||||||
|
@@ -1049,3 +1049,18 @@ void FileNameTestCase::TestShortcuts()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // __WINDOWS__
|
#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__
|
||||||
|
Reference in New Issue
Block a user