Upstream-Status: Pending

fix that top will quit after cpu offline
    
top utiliy fails to read /proc/stat after cpu offline, because Cpu_tot
is still the original cpu numbers when calling cpus_refresh, in which
it is trying to read and sscanf Cpu_tot times /proc/stat.

The patch is from procps-3.2.8-2.fc12.src.rpm

Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>

---
--- procps-3.2.7/top.c.remcpu	2006-07-10 10:41:11.000000000 +0200
+++ procps-3.2.7/top.c	2006-07-10 10:41:35.000000000 +0200
@@ -912,6 +912,7 @@
 static CPU_t *cpus_refresh (CPU_t *cpus)
 {
    static FILE *fp = NULL;
+   static int cpu_max;
    int i;
    int num;
    // enough for a /proc/stat CPU line (not the intr line)
@@ -926,24 +927,29 @@
                can hold tics representing the /proc/stat cpu summary (the first
                line read) -- that slot supports our View_CPUSUM toggle */
       cpus = alloc_c((1 + Cpu_tot) * sizeof(CPU_t));
+      cpu_max = Cpu_tot;
    }
+   else if (cpu_max > Cpu_tot)
+      /* move saved CUPs summary to cpu_max possition */
+      memcpy(&cpus[cpu_max], &cpus[Cpu_tot], sizeof(CPU_t));
+   
    rewind(fp);
    fflush(fp);
 
    // first value the last slot with the cpu summary line
    if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read");
-   cpus[Cpu_tot].x = 0;  // FIXME: can't tell by kernel version number
-   cpus[Cpu_tot].y = 0;  // FIXME: can't tell by kernel version number
-   cpus[Cpu_tot].z = 0;  // FIXME: can't tell by kernel version number
+   cpus[cpu_max].x = 0;  // FIXME: can't tell by kernel version number
+   cpus[cpu_max].y = 0;  // FIXME: can't tell by kernel version number
+   cpus[cpu_max].z = 0;  // FIXME: can't tell by kernel version number
    num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
-      &cpus[Cpu_tot].u,
-      &cpus[Cpu_tot].n,
-      &cpus[Cpu_tot].s,
-      &cpus[Cpu_tot].i,
-      &cpus[Cpu_tot].w,
-      &cpus[Cpu_tot].x,
-      &cpus[Cpu_tot].y,
-      &cpus[Cpu_tot].z
+      &cpus[cpu_max].u,
+      &cpus[cpu_max].n,
+      &cpus[cpu_max].s,
+      &cpus[cpu_max].i,
+      &cpus[cpu_max].w,
+      &cpus[cpu_max].x,
+      &cpus[cpu_max].y,
+      &cpus[cpu_max].z
    );
    if (num < 4)
          std_err("failed /proc/stat read");
@@ -955,7 +961,7 @@
    }
 
    // now value each separate cpu's tics
-   for (i = 0; 1 < Cpu_tot && i < Cpu_tot; i++) {
+   for (i = 0; ; i++) {
       if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read");
       cpus[i].x = 0;  // FIXME: can't tell by kernel version number
       cpus[i].y = 0;  // FIXME: can't tell by kernel version number
@@ -964,9 +970,35 @@
          &cpus[i].id,
          &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z
       );
-      if (num < 4)
-            std_err("failed /proc/stat read");
+      if (num < 4) {
+	 Cpu_tot = i;
+	 break;
+      }
+      if (i == cpu_max - 1) {
+	 // Bump cpu_max and extend cpus
+	 cpu_max++;
+	 cpus = realloc(cpus, (1 + cpu_max) * sizeof(CPU_t));
+	 if (!cpus) std_err("realloc failed");
+	 memcpy(&cpus[cpu_max], &cpus[cpu_max-1], sizeof(CPU_t));
+      }
+   }
+
+   if (cpu_max > Cpu_tot)
+      memcpy(&cpus[Cpu_tot], &cpus[cpu_max], sizeof(CPU_t));
+
+   // and just in case we're 2.2.xx compiled without SMP support...
+   if (Cpu_tot == 1) {
+      cpus[0].id = cpus[1].id = 0;
+      cpus[0].u = cpus[1].u;
+      cpus[0].n = cpus[1].n;
+      cpus[0].s = cpus[1].s;
+      cpus[0].i = cpus[1].i;
+      cpus[0].w = cpus[1].w;
+      cpus[0].x = cpus[1].x;
+      cpus[0].y = cpus[1].y;
+      cpus[0].z = cpus[1].z;
    }
+   
    return cpus;
 }
 
