Browse Source

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 năm trước cách đây
mục cha
commit
ae284cc5c8
1 tập tin đã thay đổi với 23 bổ sung47 xóa
  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
       {