]> granicus.if.org Git - procps-ng/commitdiff
pmap: fixing broken indentation in the -X/-XX modes
authorJaromir Capik <jcapik@redhat.com>
Wed, 6 Feb 2013 22:01:54 +0000 (23:01 +0100)
committerJaromir Capik <jcapik@redhat.com>
Fri, 15 Feb 2013 17:51:13 +0000 (18:51 +0100)
This commit changes the processing principle of the -X/-XX modes
from 1-pass to 2-pass. A separate width measurement stage has been
added, so that the real maximum widths can be measured and used
for correct indentation.

The firstmapping variable now has a new value (2) used for the
width measurement stage (1st pass). The printing is disabled
in this stage. The file position is reset to the beginning
of the file once the end of file is reached and the printing stage
(2nd pass) begins.
It's questionable if this approach is sensitive to Read-after-Write
race conditions. Anyway, this feature is a good candidate for
a complete redesign in the future.

Additionally this commit introduces a final cleaning of the list
used for the evaluation of totals in the -X/-XX modes.

pmap.c

diff --git a/pmap.c b/pmap.c
index 5a955dff2468d289fccdb72c29c4c80de949faac..6381494706d27cbdc6c60fbd48fa73b32e1ea90a 100644 (file)
--- a/pmap.c
+++ b/pmap.c
@@ -184,7 +184,7 @@ struct listnode {
        struct listnode *next;
 };
 
-static struct listnode *listhead=NULL, *listtail=NULL;
+static struct listnode *listhead=NULL, *listtail=NULL, *listnode;
 
 
 static int is_unimportant (char *s)
@@ -201,7 +201,6 @@ static int is_unimportant (char *s)
 
 static void print_extended_maps (FILE *f)
 {
-       struct listnode *listnode;
        char flags[DETAIL_LENGTH], map_desc[128],
             detail_desc[DETAIL_LENGTH], value_str[NUM_LENGTH],
             start[NUM_LENGTH], end[NUM_LENGTH],
@@ -216,7 +215,7 @@ static void print_extended_maps (FILE *f)
        char has_vmflags = 0;
 
        ret = fgets(mapbuf, sizeof mapbuf, f);
-       firstmapping = 1;
+       firstmapping = 2;
        while (ret != NULL) {
                /* === READ MAPPING === */
                map_desc[0] = '\0';
@@ -254,7 +253,7 @@ static void print_extended_maps (FILE *f)
                                goto loop_end;
                        /* === CREATE LIST AND FILL description FIELD === */
                        if (listnode == NULL) {
-                               assert(firstmapping == 1);
+                               assert(firstmapping == 2);
                                listnode = calloc(1, sizeof *listnode);
                                if (listhead == NULL) {
                                        assert(listtail == NULL);
@@ -271,15 +270,14 @@ static void print_extended_maps (FILE *f)
                                        listnode->max_width = 7;
                        } else {
                        /* === LIST EXISTS  === */
-                               if ((listnode == NULL) ||
-                                   (strcmp(listnode->description, detail_desc) != 0))
+                               if (strcmp(listnode->description, detail_desc) != 0)
                                        xerrx(EXIT_FAILURE, "ERROR: %s %s",
                                              _("inconsistent detail field in smaps file, line:\n"),
                                              mapbuf);
                        }
                        strcpy(listnode->value_str, value_str);
                        sscanf(value_str, "%"KLF"u", &listnode->value);
-                       listnode->total += listnode->value;
+                       if (firstmapping == 2) listnode->total += listnode->value;
                        if (strlen(value_str) > listnode->max_width)
                                listnode->max_width = strlen(value_str);
                        listnode = listnode->next;
@@ -297,51 +295,60 @@ loop_end:
                        if (strlen(vmflags) > maxwv) maxwv = strlen(vmflags);
                }
 
-               /* === PRINT THIS MAPPING === */
-               /* Print header */
-               if (firstmapping && !q_option) {
-                       if (strlen("Address") > maxw1)  maxw1 = strlen("Address");
-                       if (strlen("Flags") > maxw2)    maxw2 = strlen("Flags");
-                       if (strlen("Offset") > maxw3)   maxw3 = strlen("Offset");
-                       if (strlen("Device") > maxw4)   maxw4 = strlen("Device");
-                       if (strlen("Inode") > maxw5)    maxw5 = strlen("Inode");
-                       if (has_vmflags && strlen("VmFlags") > maxwv)   maxwv = strlen("VmFlags");
+               if (firstmapping == 2) { /* width measurement stage, do not print anything yet */
+                       if (ret == NULL) {      /* once the end of file is reached ...*/
+                               firstmapping = 1;  /* ... we reset the file position to the beginning of the file */
+                               fseek(f, 0, SEEK_SET);  /* ... and repeat the process with printing enabled */
+                               ret = fgets(mapbuf, sizeof mapbuf, f); /* this is not ideal and needs to be redesigned one day */
+                       }
+               } else {                 /* the maximum widths have been measured, we've already reached the printing stage */
+                       /* === PRINT THIS MAPPING === */
+                       /* Print header */
+                       if (firstmapping && !q_option) {
+                               if (strlen("Address") > maxw1)  maxw1 = strlen("Address");
+                               if (strlen("Flags") > maxw2)    maxw2 = strlen("Flags");
+                               if (strlen("Offset") > maxw3)   maxw3 = strlen("Offset");
+                               if (strlen("Device") > maxw4)   maxw4 = strlen("Device");
+                               if (strlen("Inode") > maxw5)    maxw5 = strlen("Inode");
+                               if (has_vmflags && strlen("VmFlags") > maxwv)   maxwv = strlen("VmFlags");
+                               sprintf(fmt_str, "%%%ds %%%ds %%%ds %%%ds %%%ds",
+                                       maxw1, maxw2, maxw3, maxw4, maxw5);
+                               printf(fmt_str, "Address", "Flags", "Offset", "Device", "Inode");
+
+                               for (listnode=listhead; listnode=listnode->next;
+                                    listnode!=NULL) {
+                                       sprintf(fmt_str, " %%%ds", listnode->max_width);
+                                       printf(fmt_str, listnode->description);
+                               }
+
+                               if (has_vmflags) {
+                                       sprintf(fmt_str, " %%%ds", maxwv);
+                                       printf(fmt_str, "VmFlags");
+                               }
+
+                               printf(" %s\n", "Description");
+                       }
+                       /* Print data */
                        sprintf(fmt_str, "%%%ds %%%ds %%%ds %%%ds %%%ds",
                                maxw1, maxw2, maxw3, maxw4, maxw5);
-                       printf(fmt_str, "Address", "Flags", "Offset", "Device", "Inode");
+                       printf(fmt_str, start, flags, offset, dev, inode);
 
                        for (listnode=listhead; listnode=listnode->next;
                             listnode!=NULL) {
                                sprintf(fmt_str, " %%%ds", listnode->max_width);
-                               printf(fmt_str, listnode->description);
+                               printf(fmt_str, listnode->value_str);
                        }
 
                        if (has_vmflags) {
                                sprintf(fmt_str, " %%%ds", maxwv);
-                               printf(fmt_str, "VmFlags");
+                               printf(fmt_str, vmflags);
                        }
 
-                       printf(" %s\n", "Description");
-               }
-               /* Print data */
-               sprintf(fmt_str, "%%%ds %%%ds %%%ds %%%ds %%%ds",
-                       maxw1, maxw2, maxw3, maxw4, maxw5);
-               printf(fmt_str, start, flags, offset, dev, inode);
+                       printf(" %s\n", map_desc);
 
-               for (listnode=listhead; listnode=listnode->next;
-                    listnode!=NULL) {
-                       sprintf(fmt_str, " %%%ds", listnode->max_width);
-                       printf(fmt_str, listnode->value_str);
-               }
+                       firstmapping = 0;
 
-               if (has_vmflags) {
-                       sprintf(fmt_str, " %%%ds", maxwv);
-                       printf(fmt_str, vmflags);
                }
-
-               printf(" %s\n", map_desc);
-
-               firstmapping = 0;
        }
        /* === PRINT TOTALS === */
        if (!q_option && listhead!=NULL) {
@@ -722,6 +729,13 @@ int main(int argc, char **argv)
        closeproc(PT);
        free(pidlist);
 
+       /* cleaning the list used for the -X/-XX modes */
+       for (listnode = listhead; listnode != NULL ; ) {
+               listnode = listnode -> next;
+               free(listhead);
+               listhead = listnode;
+       }
+
        if (count)
                /* didn't find all processes asked for */
                ret |= 42;