* src/du.c (main): Fail on AI_ERR_READ error, rather than merely
diagnosing and continuing. Based on a patch by Stefan Vargyas.
Also move the handling of AI_ERR_EOF into the case stmt.
Do not report ferror/fclose(stdin) failure when we've
already diagnosed e.g., failure to read the DIR, above.
Bug introduced by 2008-11-24 commit
031e2fb5, "du: read and
process --files0-from= input a name at a time,".
* src/wc.c: Handle read failure as with du: do not exit
immediately, but rather go on to print any total and to clean-up.
As above, move the handling of AI_ERR_EOF into the case stmt.
* tests/du/files0-from-dir: New file, to test both du and wc.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Bug fixes): Mention it.
** Bug fixes
+ du would infloop when given --files0-from=DIR
+ [bug introduced in coreutils-7.1]
+
cut could segfault when invoked with a user-specified output
delimiter and an unbounded range like "-f1234567890-".
[bug introduced in coreutils-5.3.0]
Solar Designer solar@owl.openwall.com
Stanislav Ievlev inger@altlinux.ru
Stavros Passas stabat@ics.forth.gr
+Stefan Vargyas stvar@yahoo.com
Stéphane Chazelas Stephane_CHAZELAS@yahoo.fr
Stephen Depooter sbdep@myrealbox.com
Stephen Eglen eglen@pcg.wustl.edu
bool skip_file = false;
enum argv_iter_err ai_err;
char *file_name = argv_iter (ai, &ai_err);
- if (ai_err == AI_ERR_EOF)
- break;
if (!file_name)
{
switch (ai_err)
{
+ case AI_ERR_EOF:
+ goto argv_iter_done;
case AI_ERR_READ:
- error (0, errno, _("%s: read error"), quote (files_from));
- continue;
-
+ error (0, errno, _("%s: read error"),
+ quotearg_colon (files_from));
+ ok = false;
+ goto argv_iter_done;
case AI_ERR_MEM:
xalloc_die ();
-
default:
assert (!"unexpected error code from argv_iter");
}
ok &= du_files (temp_argv, bit_flags);
}
}
+ argv_iter_done:
argv_iter_free (ai);
di_set_free (di_set);
- if (files_from && (ferror (stdin) || fclose (stdin) != 0))
+ if (files_from && (ferror (stdin) || fclose (stdin) != 0) && ok)
error (EXIT_FAILURE, 0, _("error reading %s"), quote (files_from));
if (print_grand_total)
bool skip_file = false;
enum argv_iter_err ai_err;
char *file_name = argv_iter (ai, &ai_err);
- if (ai_err == AI_ERR_EOF)
- break;
if (!file_name)
{
switch (ai_err)
{
+ case AI_ERR_EOF:
+ goto argv_iter_done;
case AI_ERR_READ:
- error (EXIT_FAILURE, errno, _("%s: read error"),
- quote (files_from));
- continue;
+ error (0, errno, _("%s: read error"),
+ quotearg_colon (files_from));
+ ok = false;
+ goto argv_iter_done;
case AI_ERR_MEM:
xalloc_die ();
default:
else
ok &= wc_file (file_name, &fstatus[nfiles ? i : 0]);
}
+ argv_iter_done:
/* No arguments on the command line is fine. That means read from stdin.
However, no arguments on the --files0-from input stream is an error
du/exclude \
du/fd-leak \
du/files0-from \
+ du/files0-from-dir \
du/hard-link \
du/inacc-dest \
du/inacc-dir \
--- /dev/null
+#!/bin/sh
+# ensure that du and wc handle --files0-from=DIR
+
+# Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+print_ver_ du wc
+
+mkdir dir
+
+# Skip this test if reading from a directory succeeds.
+# In that case, using --files0-from=dir would yield garbage,
+# interpreting the directory entry as a sequence of
+# NUL-separated file names.
+cat dir > /dev/null && skip_ "cat dir/ succeeds"
+
+for prog in du wc; do
+ $prog --files0-from=dir > /dev/null 2>err && fail=1
+ printf "$prog: dir:\n" > exp || fail=1
+ # The diagnostic string is usually "Is a directory" (ENOTDIR),
+ # but accept a different string or errno value.
+ sed 's/dir:.*/dir:/' err > k; mv k err
+ compare err exp || fail=1
+done
+
+Exit $fail