Remove unbounded scanfs. Also reduce the amount of allocation and
freeing by reusing the getline() buffer.

Correct syntax in help. Improve error messages.

Implement -p.

Use FLAG() and simplify implementation slightly.
---
 toys/other/pmap.c | 118 +++++++++++++++++++++-------------------------
 1 file changed, 54 insertions(+), 64 deletions(-)
From a391b7cbbdd3190b3366aae705975332ffb141e0 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <e...@google.com>
Date: Sat, 25 Sep 2021 18:40:07 -0700
Subject: [PATCH] pmap: cleanup.

Remove unbounded scanfs. Also reduce the amount of allocation and
freeing by reusing the getline() buffer.

Correct syntax in help. Improve error messages.

Implement -p.

Use FLAG() and simplify implementation slightly.
---
 toys/other/pmap.c | 118 +++++++++++++++++++++-------------------------
 1 file changed, 54 insertions(+), 64 deletions(-)

diff --git a/toys/other/pmap.c b/toys/other/pmap.c
index 02260dbd..5ccda4bb 100644
--- a/toys/other/pmap.c
+++ b/toys/other/pmap.c
@@ -4,19 +4,22 @@
  * Copyright 2013 Kyungwan Han <asura...@gmail.com>
  *
  * No Standard.
+ *
+ * TODO: two passes so we can auto-size the columns?
 
-USE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_USR|TOYFLAG_BIN))
+USE_PMAP(NEWTOY(pmap, "<1pqx", TOYFLAG_USR|TOYFLAG_BIN))
 
 config PMAP
   bool "pmap"
   default y
   help
-    usage: pmap [-xq] [pids...]
+    usage: pmap [-pqx] PID...
 
     Report the memory map of a process or processes.
 
+    -q	Show full paths
+    -q	Do not show header or footer
     -x	Show the extended format
-    -q	Do not display some header/footer lines
 */
 
 #define FOR_pmap
@@ -24,90 +27,77 @@ config PMAP
 
 void pmap_main(void)
 {
-  char **optargs;
+  char **optargs, *line = 0;
+  size_t allocated_length = 0;
 
   for (optargs = toys.optargs; *optargs; optargs++) {
+    long long start, end, pss, tpss=0, dirty, tdirty=0, swap, tswap=0, total=0;
+    char *name = 0, *k = FLAG(x) ? "" : "K", mode[5];
     pid_t pid = atolx(*optargs);
+    int extras = 0, off, count;
     FILE *fp;
-    char *line, *oldline = 0, *name = 0,
-         *k = (toys.optflags & FLAG_x) ? "" : "K";
-    size_t len;
-    long long start, end, pss, tpss = 0, dirty, tdirty = 0, swap, tswap = 0,
-              total = 0;
-    int xx = 0;
 
-    snprintf(toybuf, sizeof(toybuf), "/proc/%u/cmdline", pid);
-    line = readfile(toybuf, 0, 0);
-    if (!line) error_msg("No %lu", (long)pid);
-    xprintf("%u: %s\n", (int)pid, line);
-    free(line);
+    sprintf(toybuf, "/proc/%u/cmdline", pid);
+    if (!(name = readfile(toybuf, 0, 0))) {
+      error_msg("no %s", toybuf);
+      continue;
+    }
+    xprintf("%d: %s\n", pid, name);
+    free(name);
 
-    // Header
-    // Only use the more verbose file in -x mode
-    sprintf(toybuf, "/proc/%u/%smaps", pid,
-      (toys.optflags & FLAG_x) ? "s" : "");
+    // Only bother scanning the more verbose smaps file in -x mode.
+    sprintf(toybuf, "/proc/%u/%smaps", pid, FLAG(x) ? "s" : "");
     if (!(fp = fopen(toybuf, "r"))) {
-      error_msg("No %ld\n", (long)pid);
-      return;
+      error_msg("no %s", toybuf);
+      continue;
     }
 
-    if ((toys.optflags & (FLAG_q|FLAG_x)) == FLAG_x)
-      xprintf("Address%*cKbytes     PSS   Dirty    Swap  Mode  Mapping\n",
-        (int)(sizeof(long)*2)-4, ' ');
-
-    // Loop through mappings
-    for (;;) {
-      int off, count;
-
-      line = 0;
-      if (0 >= getline(&line, &len, fp)) break;
-      count = sscanf(line, "%llx-%llx %s %*s %*s %*s %n",
-        &start, &end, toybuf, &off);
+    if (FLAG(x) && !FLAG(q))
+      xprintf("Address%*cKbytes     PSS   Dirty    Swap Mode  Mapping\n",
+          (int)(sizeof(long)*2)-5, ' ');
 
+    while (getline(&line, &allocated_length, fp) > 0) {
+      count = sscanf(line, "%llx-%llx %4s %*s %*s %*s %n", &start, &end, mode,
+          &off);
       if (count == 3) {
         name = line[off] ? line+off : "  [anon]\n";
-        if (toybuf[3] == 'p') toybuf[3] = '-';
+        if (mode[3] == 'p') mode[3] = '-';
         total += end = (end-start)/1024;
-        printf("%0*llx % *lld%s ", (int)(2*sizeof(long)), start,
-          6+!!(toys.optflags & FLAG_x), end, k);
-        if (toys.optflags & FLAG_x) {
-          oldline = line;
+        printf("%0*llx % *lld%s ", (int)(2*sizeof(long)), start, 6+!!FLAG(x),
+            end, k);
+        if (FLAG(x)) {
+          strcpy(toybuf, name);
+          name = toybuf;
           continue;
         }
       } else {
-        if (0<sscanf(line, "Pss: %lld", &pss)
-            || 0<sscanf(line, "Private_Dirty: %lld", &dirty)
-            || 0<sscanf(line, "Swap: %lld", &swap)) xx++;
-        free(line);
-        if (xx<3) continue;
-        line = oldline;
-        name = basename(name);
-        xx = 0;
-        printf("% 7lld %7lld %7lld ", pss, dirty, swap);
-        tpss += pss;
-        tdirty += dirty;
-        tswap += swap;
+        if (sscanf(line, "Pss: %lld", &pss) ||
+            sscanf(line, "Private_Dirty: %lld", &dirty) ||
+            sscanf(line, "Swap: %lld", &swap)) extras++;
+        if (extras==3) {
+          printf("% 7lld %7lld %7lld ", pss, dirty, swap);
+          tpss += pss;
+          tdirty += dirty;
+          tswap += swap;
+          extras = 0;
+        } else continue;
       }
 
-      xprintf("%s-  %s%s", toybuf, line[off]=='[' ? "  " : "", name);
-
-      free(line);
-      line = 0;
+      xprintf("%s- %s%s", mode, *name == '[' ? "  " : "",
+              FLAG(p) ? name : basename(name));
     }
 
-    // Trailer
-    if (!(toys.optflags & FLAG_q)) {
-      int x = !!(toys.optflags & FLAG_x);
-      if (x) {
-        memset(toybuf, '-', 16);
-        xprintf("%.*s  ------  ------  ------  ------\n", (int)(sizeof(long)*2),
-          toybuf);
+    if (!FLAG(q)) {
+      if (FLAG(x)) {
+        xprintf("----------------  ------  ------  ------  ------\n" +
+            ((sizeof(long)==4)?8:0));
       }
-      printf("total% *lld%s", 2*(int)(sizeof(long)+1)+x, total, k);
-      if (x) printf("% 8lld% 8lld% 8lld", tpss, tdirty, tswap);
+      printf("total% *lld%s", 2*(int)(sizeof(long)+1)+!!FLAG(x), total, k);
+      if (FLAG(x)) printf("% 8lld% 8lld% 8lld", tpss, tdirty, tswap);
       xputc('\n');
     }
- 
+
     fclose(fp);
   }
+  free(line);
 }
-- 
2.33.0.685.g46640cef36-goog

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to