File procinfo-intr.dif of Package procinfo

--- procinfo.c
+++ procinfo.c	2014-10-09 11:56:25.996337561 +0000
@@ -19,6 +19,9 @@
 
 static char *rcsid __attribute__ ((unused)) = "$Id: procinfo.c,v 1.56 2001/02/25 11:29:13 svm Exp svm $";
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
@@ -328,6 +331,8 @@ first_page (long sl)
 	    new.cpu_iowait = VAL;
 	    new.cpu_hirq = VAL;
 	    new.cpu_sirq = VAL;
+	    new.cpu_steal = VAL;
+	    new.cpu_guest = VAL;
 	    /*
 	     * according to bug #1959, sometimes the cpu_idle
 	     * seems to go backwards(!) on SMP boxes.  This may
@@ -412,11 +417,34 @@ first_page (long sl)
 	    new.swout = VAL;
 	} else if (ISSTR ("intr")) {
 	    if (nr_irqs) {
+		size_t len = strlen(&line[5]);
+		char *tok, *lp = &line[5+len-1];
+
 		VAL;		/* First value is total of all interrupts,
 				   for compatibility with rpc.rstatd. We
 				   ignore it. */
+
+		tok = (char*)0;
 		for (i = 0; i < nr_irqs; i++) {
-		    new.intr[i] = VAL;
+		    char * cp = strtok(tok, " ");
+		    if (!cp)
+			break;
+		    new.intr[i] = strtoul(cp, NULL, 10);
+		    tok = (char*)0;
+
+		    if (*lp != '\n') {
+			off_t off = cp - line + strlen(cp) + 1;
+			if (off + sizeof(line)/4 > sizeof(line)) {
+			    size_t rest = strlen(&line[off]);
+			    memmove((tok = &line[0]), &line[off], rest+1);
+			    if (!fgets(&line[rest], sizeof(line) - rest, statfp)) {
+				*lp = '\n';
+				continue;
+			    }
+			    len = strlen(&line[rest]);
+			    lp = &line[rest+len-1];
+			}
+		    }
 		}
 	    } else
 		new.old_intr = VAL;
@@ -535,6 +563,19 @@ first_page (long sl)
     else
 	putchar ('\n');
 
+    if (havetwosix) {
+	if (new.cpu_steal) {
+	    printf ("steal : %s %s",
+		hms (bDIFF (cpu_steal)), perc (bDIFF (cpu_steal), elapsed, nr_cpus));
+	    putchar ('\n');
+	}
+	if (new.cpu_guest) {
+	    printf ("guest : %s %s",
+		hms (bDIFF (cpu_guest)), perc (bDIFF (cpu_guest), elapsed, nr_cpus));
+	    putchar ('\n');
+	}
+    }
+
     printf ("uptime: %s         context :%11lu", hms (new.uptime),
 	    bDIFF (ctxt));
     if (new.syscalls)	/* If we have this, we can use the old interrupts spot. */
@@ -543,66 +584,72 @@ first_page (long sl)
 /****= /proc/interrupts =****/
 
     if (nr_irqs) {
-	char irq_label[nr_irqs][22];
+	char emtpy[1] = { '\0' };
+	struct irq_s { char *label; } irq[nr_irqs];
 
-	memset (irq_label, 0, nr_irqs * 22);
+	for (i = 0; i < nr_irqs; i++)
+	    irq[i].label = &emtpy[0];
 
 	if (interruptsfp) {
 	    int i;
 
 	    fseek (interruptsfp, 0L, SEEK_SET);
 	    while (fgets (line, sizeof (line), interruptsfp)) {
-		char *p;
+		char *q, *p;
+		int n;
 
-		if (!strchr(line, ':'))		/* skip "           CPU0" */
+		if (!(q = strchr(line, ':')))		/* Skip CPU0 ... */
 		    continue;
+		p = &line[0];
+		*q = '\0';
 
-		i = atol (strtok (line, ":")); /* Get the IRQ no. */
+		while (*p == ' ')
+		   p++;
 
-		p = strtok (NULL, "\n");
+		if ((*p < '0') || (*p > '9'))		/* Skip NMI, LOC, ... */
+		    continue;
 
-		/*
-		  Left: p = "      31273 + serial"
-		  or    p = "         1   XT PIC   serial"
-		  or    p = "         1  IO-APIC   serial"
-		  or whatever.
-		  Anyway, let's first gobble up...
-		*/
+		i = atol(p);				/* Get the IRQ no. */
 
-		while (*p == ' ')		/* ...spaces... */
-		    p++;
-		while (*p >= '0' && *p <= '9')	/* ...digits... */
-		    p++;
-		while (*p == ' ' || *p == '+')	/* ...and the rest. */
+		if (i >= nr_irqs)			/* Should not happen */
+		    continue;
+
+		q++;
+		while (*q == ' ')			/* Eat white spaces */
+		    q++;
+
+		n = 0;
+		while (n < nr_cpus) {
+		    if (*q == '\0' || *q == '\n')
+			break;
+		    p = q;
+		    if (!(q = strchr(p, ' ')))		/* Skip no. of IRQ */
+			break;
+		    while (*q == ' ')			/* Eat white spaces */
+			q++;
+		    n++;
+		}					/* Do this for all CPUs */
+
+		if (!q || (*q == '\0') || (*q == '\n'))
+		    continue;
+
+		if (!(p = strchr(q, ' ')))		/* Skip type of IRQ */
+		    continue;
+
+		while (*p == ' ')			/* Eat white spaces */
 		    p++;
 
-		/* Left: "serial" or "XT PIC   serial" */
+		if ((q = strchr(p, '\n')))		/* Eat newline character */
+		    *q = '\0';
 
-		if (linux_version_code >= 0x20150) {
-		    /*
-		      I don't really like hardcoding version numbers, but
-		      since the label itself may contain spaces, I can't
-		      think of a fool-proof algorithm to detect a "XT PIC"
-		      style /proc/interrupts.
-		    */
-		    char *q;
-
-		    if ((q = strstr (p, "PIC"))) {
-			while (*q != ' ')	/* eat up "PIC" or "PIC-foo" */
-			    q++;
-			while (*q == ' ')	/* eat up spaces */
-			    q++;
-			p = q;
-		    }
+		if (*(irq[i].label) == 0) {
+		    irq[i].label = strndupa(p, 21);
+		    if (irq[i].label == (char*)0)
+			irq[i].label = &emtpy[0];
 		}
-
-		/* XXX Don't let NMI:, IPI: overwrite real values */
-		if (irq_label[i][0] == 0)
-		    strncpy (irq_label[i], p, 20);
 	    }
 	}
 
-
 /**** /proc/dma ****/
 
 	if (dmafp) {
@@ -612,18 +659,49 @@ first_page (long sl)
 
 	    fseek (dmafp, 0L, SEEK_SET);
 	    while (fgets (line, sizeof (line), dmafp)) {
-		int foo = strcspn (&line[4], " \n");
+		char *q, *p;
+		size_t len;
+		int num;
+
+		q = strchr(line, ':');
+		if (!q || (*q == '\0') || (*q == '\n'))
+		    continue;
+
+		p = &line[0];
+		*q = '\0';
+
+		while (*p == ' ')			/* Eat white spaces */
+		    p++;
+		num = atol(p);
+
+		q++;
+		while (*q == ' ')			/* Eat white spaces */
+		    q++;
+
+		if ((p = strchr(q, '\n')))		/* Eat newline character */
+		    *p = '\0';
+
+		if ((p = strchr(q, ' ')))		/* Forget rest of line */
+		    *p = '\0';
+		len = strlen(q);
 
 		for (i = 0; i < nr_irqs; i++) {
-		    if (strncmp (&line[4], irq_label[i], foo) == 0) {
-			tmplen = sprintf (tmp, " [%ld]",
-					  atol (strtok (line, ":")));
+		    struct irq_s *s = &irq[i];
 
-			if (strlen (irq_label[i]) > (21 - tmplen)) {
-			    irq_label[i][21 - tmplen] = 0;
+		    if (*(s->label) == '\0')
+			continue;
 
-			}
-			strcat (irq_label[i], tmp);
+		    if (strncmp (q, s->label, len) == 0) {
+			tmplen = snprintf(tmp, sizeof(tmp), " [%d]", num);
+
+			if (tmplen > 21)		/* Should not happen */
+			    continue;
+			tmp[tmplen] = '\0';
+
+			if (strlen(s->label) > (21 - tmplen))
+			    s->label[21 - tmplen] = 0;
+
+			strcat (s->label, tmp);
 		    }
 		}
 	    }
@@ -640,10 +718,11 @@ first_page (long sl)
 	    } squirqs[nr_irqs];
 
 	    for (i = 0; i < nr_irqs; i++) {
-		if (new.intr[i] || irq_label[i][0]) {
+		struct irq_s *s = &irq[i];
+		if (new.intr[i] || *(s->label)) {
 		    squirqs[howmany].nr = i;
 		    squirqs[howmany].count = bDIFF(intr[i]);
-		    squirqs[howmany].label = irq_label[i];
+		    squirqs[howmany].label = s->label;
 		    howmany++;
 		}
 	    }
@@ -653,11 +732,11 @@ first_page (long sl)
 	    for (i = 0; i < rows; i++) {
 		/* The last row may be incomplete if howmany is odd, hence: */
 		if (i == rows - 1 && howmany & 1) {
-		    printf ("irq%3d:%10lu %-21s\n",
+		    printf ("irq%4d:%10lu %-20s\n",
 			    squirqs[i].nr, squirqs[i].count, squirqs[i].label);
 		} else {
-		    printf ("irq%3d:%10lu %-21s "
-			    "irq%3d:%10lu %-21s\n",
+		    printf ("irq%4d:%10lu %-20s "
+			    "irq%4d:%10lu %-20s\n",
 			    squirqs[i].nr, squirqs[i].count, squirqs[i].label,
 			    squirqs[i+rows].nr,
 			    squirqs[i+rows].count,
@@ -665,13 +744,15 @@ first_page (long sl)
 		}
 	    }
 	} else {
-	    for (i = 0; i < nr_irqs / 2; i++)
+	    for (i = 0; i < nr_irqs / 2; i++) {
+		int j = i+(nr_irqs/2);
+		struct irq_s *s = &irq[i];
+		struct irq_s *r = &irq[j];
 		printf ("irq%3d:%10lu %-21s "
 			"irq%3d:%10lu %-21s\n",
-			i, bDIFF (intr[i]), irq_label[i],
-			i + (nr_irqs / 2),
-			bDIFF (intr[i + (nr_irqs / 2)]),
-			irq_label[i + (nr_irqs / 2)]);
+			i, bDIFF (intr[i]), s->label,
+			j, bDIFF (intr[j]), r->label);
+	    }
 	}
 
     } else
@@ -834,7 +915,7 @@ int
 main (int ac, char **av)
 {
     long sl = 5000000L;
-    int getoptopt;
+    int getoptopt, scanintr;
     struct timeval then, now;
 #ifndef DEBUG
     char outbuf[4096];
@@ -993,19 +1074,23 @@ main (int ac, char **av)
     version = make_version (versionfp);
 
     /* See what the intr line in /proc/stat says. */
+    scanintr = 0;
     while (fgets (line, sizeof (line), statfp)) {
-	if (!strncmp ("intr", line, 4)) {
+	if (scanintr || !strncmp("intr", line, 4)) {
 	    /* Counting number of spaces after line[5] gives us */
 	    /* number of interrupt entries in new-style intr. */
 	    /* If zero: old style intr. */
-	    int i, len = strlen(line);
-	    for(i = 5; i < len; i++)
-		if(line[i] == ' ')
+	    size_t i, len = strlen(line);
+	    for(i = ((scanintr) ? 0 : 5); i < len; i++) {
+		if (line[i] == '\n')
+		    break;
+		if (line[i] == ' ')
 		    nr_irqs++;
-	    new.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
-	    old.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
-	    memset (&base, 0, sizeof (struct info));
-	    base.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+	    }
+	    if (line[i] != '\n')
+		scanintr = 1;
+	    else
+		scanintr = 0;
 	    continue;
 	}
 	/* While we're at it, fill in booted. */
@@ -1017,6 +1102,12 @@ main (int ac, char **av)
 	    continue;
 	}
     }
+    if (nr_irqs) {
+	new.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+	old.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+	memset (&base, 0, sizeof (struct info));
+	base.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+    }
 
     if (fs)
 	printf ("%s%s", cl, vi);
--- procinfo.h
+++ procinfo.h	2008-04-28 13:14:11.000000000 +0200
@@ -83,7 +83,7 @@ struct info
     unsigned long uptime;
     long m_to, m_us, m_fr, m_sh, m_bu, m_ca;
     long s_to, s_us, s_fr;
-    unsigned long cpu_user, cpu_nice, cpu_sys, cpu_idle, cpu_iowait, cpu_hirq, cpu_sirq;
+    unsigned long cpu_user, cpu_nice, cpu_sys, cpu_idle, cpu_iowait, cpu_hirq, cpu_sirq, cpu_steal, cpu_guest;
     unsigned long disk[8];
     unsigned long disk_r[8];
     unsigned long disk_w[8];
--- routines.c
+++ routines.c	2014-10-09 11:47:57.891838889 +0000
@@ -430,22 +430,21 @@ hms (unsigned long t)
 char *
 perc (unsigned long i, unsigned long t, int cpus)
 {
-    unsigned int v;
+    long double v;
     static char buf[128];
 
     t = (t*100ULL) / usr_hz;
     if ((signed long) i == -1 || t == 0)
 	return "---.-%";
 
-    v = (unsigned int) (i < 1000000 ?
-			((1000 * i + t / 2) / t) :
-			((i + t / 2000) / (t / 1000)));
-    v /= cpus;
+    if (i < 1000000UL)
+	v = (1000.0 * i + t / 2.0) / t;
+    else
+	v = (i + t / 2000.0) / (t / 1000.0);
+    v = v / (cpus * 10.0);
 
-    /* if (v > 1000)
-	return "+++.+%";
-    else */
-	snprintf (buf, sizeof(buf)-1, "%3u.%u%%", v / 10, v % 10);
+    buf[0] = '\0';
+    snprintf (buf, sizeof(buf)-1, "%5.1Lf%%", v);
     return buf;
 }
 
openSUSE Build Service is sponsored by