]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
dd: always diagnose partial writes on write failure
authorPádraig Brady <P@draigBrady.com>
Wed, 11 Mar 2026 15:39:20 +0000 (15:39 +0000)
committerPádraig Brady <P@draigBrady.com>
Thu, 12 Mar 2026 21:19:33 +0000 (21:19 +0000)
* src/dd.c (dd_copy): Increment the partial write count upon failure.
* tests/dd/partial-write.sh: Add a new test.
* tests/local.mk: Reference the new test.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/80583

NEWS
src/dd.c
tests/dd/partial-write.sh [new file with mode: 0755]
tests/local.mk

diff --git a/NEWS b/NEWS
index cc345d48e0ae057454e4b8e2b2dcbd18dc3ba7e2..bbd2eeba03f9938ae6cd7f796a037c4a35c2f2ce 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,10 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** Bug fixes
 
+  'dd' now always diagnoses partial writes correctly upon write failure.
+  Previously it may have indicated that only full writes were performed.
+  [This bug was present in "the beginning".]
+
   'fold' will no longer truncate output when encountering 0xFF bytes.
   [bug introduced in coreutils-9.8]
 
index 07b1c6445df7b16898bb2a9db1b396aec7d11a66..5451b0ac917b8832449a89ea3dbbb6eb7bf8d77a 100644 (file)
--- a/src/dd.c
+++ b/src/dd.c
@@ -2264,6 +2264,8 @@ dd_copy (void)
           if (nwritten != n_bytes_read)
             {
               diagnose (errno, _("error writing %s"), quoteaf (output_file));
+              if (nwritten != 0)
+                w_partial++;
               return EXIT_FAILURE;
             }
           else if (n_bytes_read == input_blocksize)
diff --git a/tests/dd/partial-write.sh b/tests/dd/partial-write.sh
new file mode 100755 (executable)
index 0000000..2c30194
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+# Ensure partial writes are properly diagnosed
+
+# Copyright (C) 2026 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ dd
+
+(
+  ulimit -S -f 1024 || skip_ 'unable to set file size ulimit'
+  trap '' XFSZ || skip_ 'unable to ignore SIGXFSZ'
+  dd if=/dev/zero of=f bs=768K count=2 2>err
+)
+ret=$?
+
+if test $ret = 1; then
+  grep -F '+1 records out' err || { cat err; fail=1; }
+elif test $ret = 0; then
+  skip_ 'The system did not limit the file fize'
+else
+  framework_failure_
+fi
+
+Exit $fail
index 15766df16bd9fcb1dee6f79648328fde4a3066a8..f9cbf9a5d435d817ad48c6463a7b950d90396908 100644 (file)
@@ -612,6 +612,7 @@ all_tests =                                 \
   tests/dd/nocache_eof.sh                      \
   tests/dd/nocache_fail.sh                     \
   tests/dd/not-rewound.sh                      \
+  tests/dd/partial-write.sh                    \
   tests/dd/reblock.sh                          \
   tests/dd/skip-seek.pl                                \
   tests/dd/skip-seek2.sh                       \