No need to re-strdup things in a loop of getline - since we are using
popen to get the output in the first place, we can use the shell to
hand us just the final line.

Signed-off-by: Eric Blake <[email protected]>
---

Even though the POSIX folks ruled today that our "ab"use of a
getline() loop to determine the final line of du output was
non-portable [1], I was still miffed at the malloc overhead that our
workaround for rawhide glibc entailed.  So this is the result I came
up with.

[1] https://www.austingroupbugs.net/bug_view_page.php?bug_id=1953

 plugins/linuxdisk/filesystem.c | 28 +++++++---------------------
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/plugins/linuxdisk/filesystem.c b/plugins/linuxdisk/filesystem.c
index 283af61a..aa4615e6 100644
--- a/plugins/linuxdisk/filesystem.c
+++ b/plugins/linuxdisk/filesystem.c
@@ -148,7 +148,7 @@ create_filesystem (struct virtual_disk *disk)
 static int64_t
 estimate_size (void)
 {
-  CLEANUP_FREE char *command = NULL, *line = NULL, *lastline = NULL;
+  CLEANUP_FREE char *command = NULL, *line = NULL;
   size_t len = 0;
   FILE *fp;
   int64_t ret;
@@ -162,6 +162,7 @@ estimate_size (void)
   }
   fprintf (fp, "du -c -k -s ");
   shell_quote (dir, fp);
+  fprintf (fp, "| tail -n1");
   if (fclose (fp) == EOF) {
     nbdkit_error ("memstream failed: %m");
     return -1;
@@ -175,21 +176,11 @@ estimate_size (void)
     return -1;
   }

-  /* Ignore everything up to the last line. */
-  len = 0;
-  while (getline (&line, &len, fp) != -1) {
-    nbdkit_debug ("du: %s", line);
-    free (lastline);
-    lastline = strndup (line, len);
-    if (lastline == NULL) {
-      nbdkit_error ("strndup: %m");
-      pclose (fp);
-      return -1;
-    }
-  }
-  if (ferror (fp)) {
+  /* Should only be one line of input. */
+  if (getline (&line, &len, fp) == -1 || ferror (fp)) {
     nbdkit_error ("getline failed: %m");
     pclose (fp);
+    free (line);
     return -1;
   }

@@ -201,14 +192,9 @@ estimate_size (void)
   if (exit_status_to_nbd_error (r, "pclose: du") == -1)
     return -1;

-  if (lastline == NULL) {
-    nbdkit_error ("no output from du command");
-    return -1;
-  }
-
   /* Parse the last line. */
-  if (sscanf (lastline, "%" SCNi64, &ret) != 1 || ret < 0) {
-    nbdkit_error ("could not parse last line from du command: %s", lastline);
+  if (sscanf (line, "%" SCNi64, &ret) != 1 || ret < 0) {
+    nbdkit_error ("could not parse last line from du command: %s", line);
     return -1;
   }

-- 
2.51.1
_______________________________________________
Libguestfs mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to