Преглед на файлове

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.
Brad King преди 16 години
родител
ревизия
ae284cc5c8
променени са 1 файла, в които са добавени 23 реда и са изтрити 47 реда
  1. 23 47
      Source/kwsys/SystemInformation.cxx

+ 23 - 47
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
       {