mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
Ensure that cat works with any of the options, -A -v -e -E -T,
when applied to files in /proc and /sys, even when the FIONREAD ioctl produces nonsensical results. Before this change, cat would produce no output (or truncated output), for some linux kernels. * src/cat.c (write_pending): New function, factored out of cat. (cat): Also interpret a negative ioctl/FIONREAD count as indicating that there are bytes to read. Some versions of linux-2.6.16 do that. Write any pending output before returning. Reported by Dan Jacobson in <http://bugs.debian.org/370583>. * NEWS: Mention this bug fix. * tests/misc/cat-proc: New file. Test for the above. * tests/misc/Makefile.am (TESTS): Add cat-proc.
This commit is contained in:
18
ChangeLog
18
ChangeLog
@@ -1,7 +1,23 @@
|
||||
2006-06-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
2006-06-08 Jim Meyering <jim@meyering.net>
|
||||
|
||||
* Version 6.0-cvs.
|
||||
|
||||
Ensure that cat works with any of the options, -A -v -e -E -T,
|
||||
when applied to files in /proc and /sys, even when the FIONREAD
|
||||
ioctl produces nonsensical results. Before this change, cat would
|
||||
produce no output (or truncated output), for some linux kernels.
|
||||
|
||||
* src/cat.c (write_pending): New function, factored out of cat.
|
||||
(cat): Also interpret a negative ioctl/FIONREAD count as indicating
|
||||
that there are bytes to read. Some versions of linux-2.6.16 do that.
|
||||
Write any pending output before returning.
|
||||
Reported by Dan Jacobson in <http://bugs.debian.org/370583>.
|
||||
* NEWS: Mention this bug fix.
|
||||
* tests/misc/cat-proc: New file. Test for the above.
|
||||
* tests/misc/Makefile.am (TESTS): Add cat-proc.
|
||||
|
||||
2006-06-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* src/expr.c (eval4): Detect overflow properly when multiplying
|
||||
INTMAX_MIN * -1.
|
||||
|
||||
|
||||
4
NEWS
4
NEWS
@@ -138,6 +138,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
** Bug fixes
|
||||
|
||||
cat with any of the options, -A -v -e -E -T, when applied to a
|
||||
file in /proc or /sys (linux-specific), would truncate its output,
|
||||
usually printing nothing.
|
||||
|
||||
cp -p would fail in a /proc-less chroot, on some systems
|
||||
|
||||
When `cp -RL' encounters the same directory more than once in the
|
||||
|
||||
32
src/cat.c
32
src/cat.c
@@ -1,5 +1,5 @@
|
||||
/* cat -- concatenate files and print on the standard output.
|
||||
Copyright (C) 88, 90, 91, 1995-2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 88, 90, 91, 1995-2006 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
|
||||
@@ -195,6 +195,22 @@ simple_cat (
|
||||
}
|
||||
}
|
||||
|
||||
/* Write any pending output to STDOUT_FILENO.
|
||||
Pending is defined to be the *BPOUT - OUTBUF bytes starting at OUTBUF.
|
||||
Then set *BPOUT to OUTPUT if it's not already that value. */
|
||||
|
||||
static inline void
|
||||
write_pending (char *outbuf, char **bpout)
|
||||
{
|
||||
size_t n_write = *bpout - outbuf;
|
||||
if (0 < n_write)
|
||||
{
|
||||
if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
*bpout = outbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
|
||||
Return true if successful.
|
||||
Called if any option more than -u was specified.
|
||||
@@ -291,6 +307,7 @@ cat (
|
||||
|
||||
if (bpin > eob)
|
||||
{
|
||||
bool input_pending = false;
|
||||
#ifdef FIONREAD
|
||||
int n_to_read = 0;
|
||||
|
||||
@@ -318,15 +335,12 @@ cat (
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (n_to_read == 0)
|
||||
if (n_to_read != 0)
|
||||
input_pending = true;
|
||||
#endif
|
||||
{
|
||||
size_t n_write = bpout - outbuf;
|
||||
|
||||
if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
bpout = outbuf;
|
||||
}
|
||||
if (input_pending)
|
||||
write_pending (outbuf, &bpout);
|
||||
|
||||
/* Read more input into INBUF. */
|
||||
|
||||
@@ -334,11 +348,13 @@ cat (
|
||||
if (n_read == SAFE_READ_ERROR)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
write_pending (outbuf, &bpout);
|
||||
newlines2 = newlines;
|
||||
return false;
|
||||
}
|
||||
if (n_read == 0)
|
||||
{
|
||||
write_pending (outbuf, &bpout);
|
||||
newlines2 = newlines;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ TESTS_ENVIRONMENT = \
|
||||
# will execute the test script rather than the standard utility.
|
||||
|
||||
TESTS = \
|
||||
cat-proc \
|
||||
base64 \
|
||||
basename \
|
||||
close-stdout \
|
||||
|
||||
42
tests/misc/cat-proc
Executable file
42
tests/misc/cat-proc
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
# Ensure that cat -E produces same output as cat, module `$'s,
|
||||
# even when applied to a file in /proc.
|
||||
|
||||
if test "$VERBOSE" = yes; then
|
||||
set -x
|
||||
cat --version
|
||||
fi
|
||||
|
||||
pwd=`pwd`
|
||||
t0=`echo "$0"|sed 's,.*/,,'`.tmp; tmp=$t0/$$
|
||||
trap 'status=$?; cd $pwd; chmod -R u+rwx $t0; rm -rf $t0 && exit $status' 0
|
||||
trap '(exit $?); exit $?' 1 2 13 15
|
||||
|
||||
framework_failure=0
|
||||
mkdir -p $tmp || framework_failure=1
|
||||
cd $tmp || framework_failure=1
|
||||
|
||||
if test $framework_failure = 1; then
|
||||
echo "$0: failure in testing framework" 1>&2
|
||||
(exit 1); exit 1
|
||||
fi
|
||||
|
||||
f=/proc/cpuinfo
|
||||
test -f $f \
|
||||
|| {
|
||||
echo "$0: no $f skipping this test" 1>&2
|
||||
(exit 77); exit 77
|
||||
}
|
||||
|
||||
fail=0
|
||||
|
||||
# Yes, parts of /proc/cpuinfo might change between cat runs.
|
||||
# If that happens, consider choosing a file that's less likely to change,
|
||||
# or just filter out the changing lines.
|
||||
cat -E $f | tr -d '$' > out || fail=1
|
||||
cat $f | tr -d '$' > exp || fail=1
|
||||
|
||||
cmp out exp || fail=1
|
||||
test $fail = 1 && diff out exp 2> /dev/null
|
||||
|
||||
(exit $fail); exit $fail
|
||||
Reference in New Issue
Block a user