dd: make status=none suppress all diagnostics

* src/dd.c (STATUS_NONE): Simplify the enum so that
it's more general than just suppressing transfer counts.
Then test this in all locations where non fatal diagnostics
are output.
* tests/dd/misc.sh: Ensure the diagnostic about
being unable to skip past the end of input is suppressed.
* NEWS: Mention the change in behavior.
Fixes http://bugs.gnu.org/14897
This commit is contained in:
Pádraig Brady 2013-07-18 18:39:55 +01:00
parent 5fdb50825f
commit e6fc265b75
4 changed files with 30 additions and 20 deletions

3
NEWS
View File

@ -51,6 +51,9 @@ GNU coreutils NEWS -*- outline -*-
** Changes in behavior
dd status=none now suppresses all non fatal diagnostic messages,
not just the transfer counts.
stdbuf now requires at least one buffering mode option to be specified,
as per the documented interface.

View File

@ -8548,7 +8548,7 @@ that normally make up the last status line.
@item none
@opindex none @r{dd status=}
Do not print any informational messages to stderr.
Do not print any informational or warning messages to stderr.
Error messages are output as normal.
@end table

View File

@ -136,9 +136,7 @@ enum
enum
{
STATUS_NOXFER = 01,
STATUS_NOCOUNTS = 02,
STATUS_LAST = STATUS_NOCOUNTS,
STATUS_NONE = STATUS_LAST | (STATUS_LAST - 1)
STATUS_NONE = 02
};
/* The name of the input file, or NULL for the standard input. */
@ -738,7 +736,7 @@ print_stats (void)
double delta_s;
char const *bytes_per_second;
if ((status_flags & STATUS_NONE) == STATUS_NONE)
if (status_flags & STATUS_NONE)
return;
fprintf (stderr,
@ -1031,6 +1029,7 @@ iread (int fd, char *buf, size_t size)
if (0 < prev_nread && prev_nread < size)
{
uintmax_t prev = prev_nread;
if (!(status_flags & STATUS_NONE))
error (0, 0, ngettext (("warning: partial read (%"PRIuMAX" byte); "
"suggest iflag=fullblock"),
("warning: partial read (%"PRIuMAX" bytes); "
@ -1080,7 +1079,8 @@ iwrite (int fd, char const *buf, size_t size)
if ((output_flags & O_DIRECT) && size < output_blocksize)
{
int old_flags = fcntl (STDOUT_FILENO, F_GETFL);
if (fcntl (STDOUT_FILENO, F_SETFL, old_flags & ~O_DIRECT) != 0)
if (fcntl (STDOUT_FILENO, F_SETFL, old_flags & ~O_DIRECT) != 0
&& !(status_flags & STATUS_NONE))
error (0, errno, _("failed to turn off O_DIRECT: %s"),
quote (output_file));
@ -1573,8 +1573,10 @@ skip_via_lseek (char const *filename, int fdesc, off_t offset, int whence)
&& ioctl (fdesc, MTIOCGET, &s2) == 0
&& MT_SAME_POSITION (s1, s2))
{
error (0, 0, _("warning: working around lseek kernel bug for file (%s)\n\
of mt_type=0x%0lx -- see <sys/mtio.h> for the list of types"),
if (!(status_flags & STATUS_NONE))
error (0, 0, _("warning: working around lseek kernel bug for file "
"(%s)\n of mt_type=0x%0lx -- "
"see <sys/mtio.h> for the list of types"),
filename, s2.mt_type);
errno = 0;
new_position = -1;
@ -1745,7 +1747,7 @@ advance_input_after_read_error (size_t nbytes)
if (offset == input_offset)
return true;
diff = input_offset - offset;
if (! (0 <= diff && diff <= nbytes))
if (! (0 <= diff && diff <= nbytes) && !(status_flags & STATUS_NONE))
error (0, 0, _("warning: invalid file offset after failed read"));
if (0 <= skip_via_lseek (input_file, STDIN_FILENO, diff, SEEK_CUR))
return true;
@ -1943,7 +1945,8 @@ dd_copy (void)
1. file is too small
2. pipe has not enough data
3. partial reads */
if (us_blocks || (!input_offset_overflow && us_bytes))
if ((us_blocks || (!input_offset_overflow && us_bytes))
&& !(status_flags & STATUS_NONE))
{
error (0, 0,
_("%s: cannot skip to specified offset"), quote (input_file));
@ -2010,7 +2013,9 @@ dd_copy (void)
if (nread < 0)
{
if (!(conversions_mask & C_NOERROR) || !(status_flags & STATUS_NONE))
error (0, errno, _("error reading %s"), quote (input_file));
if (conversions_mask & C_NOERROR)
{
print_stats ();

View File

@ -32,10 +32,12 @@ ln -s $tmp_in $tmp_sym || framework_failure_
# check status=none suppresses all output to stderr
dd status=none if=$tmp_in of=/dev/null 2> err || fail=1
test -s err && fail=1
test -s err && { cat err; fail=1; }
dd status=none if=$tmp_in skip=2 of=/dev/null 2> err || fail=1
test -s err && { cat err; fail=1; }
# check status=none is cumulative with status=noxfer
dd status=none status=noxfer if=$tmp_in of=/dev/null 2> err || fail=1
test -s err && fail=1
test -s err && { cat err; fail=1; }
dd if=$tmp_in of=$tmp_out 2> /dev/null || fail=1
compare $tmp_in $tmp_out || fail=1