diff options
author | Brad King <brad.king@kitware.com> | 2009-04-06 18:55:54 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2009-04-06 18:55:54 (GMT) |
commit | ae284cc5c8701e9e2e6fe80b3f3b31e07ccb7d67 (patch) | |
tree | 348882da16b1c3834bc2e384b7b08a372581fd44 | |
parent | d6bdaf9f1371a4c5a4e88dff89855aee47e49096 (diff) | |
download | CMake-ae284cc5c8701e9e2e6fe80b3f3b31e07ccb7d67.zip CMake-ae284cc5c8701e9e2e6fe80b3f3b31e07ccb7d67.tar.gz CMake-ae284cc5c8701e9e2e6fe80b3f3b31e07ccb7d67.tar.bz2 |
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.
-rw-r--r-- | Source/kwsys/SystemInformation.cxx | 70 |
1 files changed, 23 insertions, 47 deletions
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 8770daa..41b93e3 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -2288,7 +2288,7 @@ int SystemInformationImplementation::QueryMemory() unsigned long av=0; unsigned long ap=0; - char buffer[1024]; // for skipping unused lines + char buffer[1024]; // for reading lines int linuxMajor = 0; int linuxMinor = 0; @@ -2331,56 +2331,32 @@ int SystemInformationImplementation::QueryMemory() // new /proc/meminfo format since kernel 2.6.x // Rigorously, this test should check from the developping version 2.5.x // that introduced the new format... - - unsigned long freeMem; - unsigned long buffersMem; - unsigned long cachedMem; - int status; - - status=fscanf(fd,"MemTotal:%lu kB\n", &this->TotalPhysicalMemory); - if(status==1) - { - status+=fscanf(fd,"MemFree:%lu kB\n", &freeMem); - } - if(status==2) + enum { mMemTotal, mMemFree, mBuffers, mCached, mSwapTotal, mSwapFree }; + const char* format[6] = + { "MemTotal:%lu kB", "MemFree:%lu kB", "Buffers:%lu kB", + "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,"Buffers:%lu kB\n", &buffersMem); - } - if(status==3) - { - status+=fscanf(fd,"Cached:%lu kB\n", &cachedMem); - } - 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); + for(int i=0; i < 6; ++i) + { + if(!have[i] && sscanf(buffer, format[i], &value[i]) == 1) + { + have[i] = true; + ++count; + } + } } - if(status==6) + if(count == 6) { - this->TotalVirtualMemory /= 1024; - this->AvailableVirtualMemory /= 1024; + this->TotalPhysicalMemory = value[mMemTotal] / 1024; + this->AvailablePhysicalMemory = + (value[mMemFree] + value[mBuffers] + value[mCached]) / 1024; + this->TotalVirtualMemory = value[mSwapTotal] / 1024; + this->AvailableVirtualMemory = value[mSwapFree] / 1024; } else { |