]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
dd: output final progress before syncing
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 28 Jan 2022 02:34:09 +0000 (18:34 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 28 Jan 2022 02:35:02 +0000 (18:35 -0800)
Problem reported by Sworddragon (Bug#51482).
* src/dd.c (reported_w_bytes): New var.
(print_xfer_stats): Set it.
(dd_copy): Print a final progress report if useful before
synchronizing output data.

NEWS
src/dd.c

diff --git a/NEWS b/NEWS
index 561087ccc023fa52a7d6b3d0365535316c4c2a34..15c9428bd3dcfe5e0bc017911b8de8759d331be2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,10 @@ GNU coreutils NEWS                                    -*- outline -*-
 
   The new 'date' option --resolution outputs the timestamp resolution.
 
+  With conv=fdatasync or conv=fsync, dd status=progress now reports
+  any extra final progress just before synchronizing output data,
+  since synchronizing can take a long time.
+
   sort --debug now diagnoses issues with --field-separator characters
   that conflict with characters possibly used in numbers.
 
index a6a3708f16707c7c4e60313edb4d402238811c9d..957ad129ef658a02d5f014924b37a5d22e8a9e61 100644 (file)
--- a/src/dd.c
+++ b/src/dd.c
@@ -196,6 +196,9 @@ static intmax_t r_full = 0;
 /* Number of bytes written.  */
 static intmax_t w_bytes = 0;
 
+/* Last-reported number of bytes written, or negative if never reported.  */
+static intmax_t reported_w_bytes = -1;
+
 /* Time that dd started.  */
 static xtime_t start_time;
 
@@ -815,6 +818,8 @@ print_xfer_stats (xtime_t progress_time)
     }
   else
     fputc ('\n', stderr);
+
+  reported_w_bytes = w_bytes;
 }
 
 static void
@@ -2365,6 +2370,13 @@ dd_copy (void)
         }
     }
 
+  /* fdatasync/fsync can take a long time, so issue a final progress
+     indication now if progress has been made since the previous indication.  */
+  if (conversions_mask & (C_FDATASYNC | C_FSYNC)
+      && status_level == STATUS_PROGRESS
+      && 0 <= reported_w_bytes && reported_w_bytes < w_bytes)
+    print_xfer_stats (0);
+
   if ((conversions_mask & C_FDATASYNC) && ifdatasync (STDOUT_FILENO) != 0)
     {
       if (errno != ENOSYS && errno != EINVAL)