From 0bbb9d7785957437182fc633b2d387cc51ee918e Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Wed, 9 Sep 2009 16:48:02 +0200 Subject: [PATCH] dd conv=unblock: print final newline consistently * src/dd.c (dd_copy) [C_UNBLOCK]: Always print the final newline for non-empty output, not just when output size is a multiple of cbs. * doc/coreutils.texi (dd invocation) [conv=unblock]: Mention that dd prints a newline after each output record, not just when replacing trailing spaces. Reported by Ulrich Drepper. * tests/dd/unblock: New file. Test for this. * tests/Makefile.am (TESTS): Add it. * NEWS (Bug fixes): Mention it. --- NEWS | 4 ++++ doc/coreutils.texi | 4 ++-- src/dd.c | 9 +++++---- tests/Makefile.am | 1 + tests/dd/unblock | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 6 deletions(-) create mode 100755 tests/dd/unblock diff --git a/NEWS b/NEWS index 7805fe5..26dcd59 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,10 @@ GNU coreutils NEWS -*- outline -*- printing a summary to stderr. [bug introduced in coreutils-6.11] + dd cbs=N conv=unblock would fail to print a final newline when the size + of the input was not a multiple of N bytes. + [the non-conforming behavior dates back to the initial implementation] + df no longer requires that each command-line argument be readable [bug introduced in coreutils-7.3] diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 16ff613..93f9390 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -7775,8 +7775,8 @@ input newline with a space and padding with spaces as necessary. @item unblock @opindex unblock -Replace trailing spaces in each @samp{cbs}-sized input block with a -newline. +Remove any trailing spaces in each @samp{cbs}-sized input block, +and append a newline. The @samp{block} and @samp{unblock} conversions are mutually exclusive. diff --git a/src/dd.c b/src/dd.c index 04665f9..76a31e9 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1785,10 +1785,11 @@ dd_copy (void) output_char (space_character); } - if ((conversions_mask & C_UNBLOCK) && col == conversion_blocksize) - /* Add a final '\n' if there are exactly `conversion_blocksize' - characters in the final record. */ - output_char (newline_character); + if (col && (conversions_mask & C_UNBLOCK)) + { + /* If there was any output, add a final '\n'. */ + output_char (newline_character); + } /* Write out the last block. */ if (oc != 0) diff --git a/tests/Makefile.am b/tests/Makefile.am index 42a12cf..1de53bf 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -309,6 +309,7 @@ TESTS = \ dd/skip-seek2 \ dd/skip-seek-past-file \ dd/stderr \ + dd/unblock \ dd/unblock-sync \ df/total-verify \ du/2g \ diff --git a/tests/dd/unblock b/tests/dd/unblock new file mode 100755 index 0000000..6a3634c --- /dev/null +++ b/tests/dd/unblock @@ -0,0 +1,59 @@ +#!/usr/bin/perl +# Exercise dd's conv=unblock mode + +# Copyright (C) 2009 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 . + +use strict; + +(my $program_name = $0) =~ s|.*/||; + +# Turn off localization of executable's output. +@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; +my $out = 'out'; + +my @t = + ( + # An empty test name signals that these are the arguments to use for the + # following tests. + ['', [qw (cbs=3 conv=unblock status=noxfer < )]], + ['0', '', ''], + ['1', "a\n ", "a\n\n\n"], + ['2', "a\n ", "a\n\n"], + ['3', "a ", "a\n"], + ['4', "a \n ", "a \n\n\n"], + ['5', "a \n", "a \n\n"], + ['6', "a ", "a\n\n"], + ['7', "a \n", "a\n\n\n"], + ); + +my @Tests; +my $args; +foreach my $t (@t) + { + $t->[0] eq '' + and $args = $t->[1], next; + + push @Tests, [$t->[0], @$args, {IN=>$t->[1]}, {OUT=>$t->[2]}, + {ERR_SUBST=>'s/^\d+\+\d+ records (?:in|out)$//'}, + {ERR=>"\n\n"}]; + } + +my $save_temps = $ENV{DEBUG}; +my $verbose = $ENV{VERBOSE}; + +my $prog = 'dd'; +my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); +exit $fail; -- 2.7.4