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 <eblake(a)redhat.com>
---
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