BUG: Fix parsing of linux 2.6 /proc/meminfo format
Previously KWSys SystemInformation parsed this file assuming a strict order and set of fields, but the order is not reliable. This generalizes the implementation to support any order and extra fields.
This commit is contained in:
parent
d6bdaf9f13
commit
ae284cc5c8
@ -2288,7 +2288,7 @@ int SystemInformationImplementation::QueryMemory()
|
|||||||
unsigned long av=0;
|
unsigned long av=0;
|
||||||
unsigned long ap=0;
|
unsigned long ap=0;
|
||||||
|
|
||||||
char buffer[1024]; // for skipping unused lines
|
char buffer[1024]; // for reading lines
|
||||||
|
|
||||||
int linuxMajor = 0;
|
int linuxMajor = 0;
|
||||||
int linuxMinor = 0;
|
int linuxMinor = 0;
|
||||||
@ -2331,56 +2331,32 @@ int SystemInformationImplementation::QueryMemory()
|
|||||||
// new /proc/meminfo format since kernel 2.6.x
|
// new /proc/meminfo format since kernel 2.6.x
|
||||||
// Rigorously, this test should check from the developping version 2.5.x
|
// Rigorously, this test should check from the developping version 2.5.x
|
||||||
// that introduced the new format...
|
// that introduced the new format...
|
||||||
|
|
||||||
unsigned long freeMem;
|
|
||||||
unsigned long buffersMem;
|
|
||||||
unsigned long cachedMem;
|
|
||||||
|
|
||||||
int status;
|
enum { mMemTotal, mMemFree, mBuffers, mCached, mSwapTotal, mSwapFree };
|
||||||
|
const char* format[6] =
|
||||||
status=fscanf(fd,"MemTotal:%lu kB\n", &this->TotalPhysicalMemory);
|
{ "MemTotal:%lu kB", "MemFree:%lu kB", "Buffers:%lu kB",
|
||||||
if(status==1)
|
"Cached:%lu kB", "SwapTotal:%lu kB", "SwapFree:%lu kB" };
|
||||||
|
bool have[6] = { false, false, false, false, false, false };
|
||||||
|
unsigned long value[6];
|
||||||
|
int count = 0;
|
||||||
|
while(fgets(buffer, sizeof(buffer), fd))
|
||||||
{
|
{
|
||||||
status+=fscanf(fd,"MemFree:%lu kB\n", &freeMem);
|
for(int i=0; i < 6; ++i)
|
||||||
|
{
|
||||||
|
if(!have[i] && sscanf(buffer, format[i], &value[i]) == 1)
|
||||||
|
{
|
||||||
|
have[i] = true;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(status==2)
|
if(count == 6)
|
||||||
{
|
{
|
||||||
status+=fscanf(fd,"Buffers:%lu kB\n", &buffersMem);
|
this->TotalPhysicalMemory = value[mMemTotal] / 1024;
|
||||||
}
|
this->AvailablePhysicalMemory =
|
||||||
if(status==3)
|
(value[mMemFree] + value[mBuffers] + value[mCached]) / 1024;
|
||||||
{
|
this->TotalVirtualMemory = value[mSwapTotal] / 1024;
|
||||||
status+=fscanf(fd,"Cached:%lu kB\n", &cachedMem);
|
this->AvailableVirtualMemory = value[mSwapFree] / 1024;
|
||||||
}
|
|
||||||
if(status==4)
|
|
||||||
{
|
|
||||||
this->TotalPhysicalMemory /= 1024;
|
|
||||||
this->AvailablePhysicalMemory = freeMem+cachedMem+buffersMem;
|
|
||||||
this->AvailablePhysicalMemory /= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip SwapCached, Active, Inactive, HighTotal, HighFree, LowTotal
|
|
||||||
// and LowFree.
|
|
||||||
int i=0;
|
|
||||||
bool success=status==4;
|
|
||||||
while(i<7 && success)
|
|
||||||
{
|
|
||||||
char *r=fgets(buffer, sizeof(buffer), fd); // skip a line
|
|
||||||
success=r==buffer;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(success)
|
|
||||||
{
|
|
||||||
status+=fscanf(fd,"SwapTotal:%lu kB\n", &this->TotalVirtualMemory);
|
|
||||||
}
|
|
||||||
if(status==5)
|
|
||||||
{
|
|
||||||
status+=fscanf(fd,"SwapFree:%lu kB\n", &this->AvailableVirtualMemory);
|
|
||||||
}
|
|
||||||
if(status==6)
|
|
||||||
{
|
|
||||||
this->TotalVirtualMemory /= 1024;
|
|
||||||
this->AvailableVirtualMemory /= 1024;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user