From 2662702b9e8643f62c670bbf2fa94b1be1ccf9af Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 7 Oct 2014 16:46:08 -0700 Subject: wc: don't miscount /sys and similar file systems Fix similar problems in head, od, split, tac, and tail. Reported by George Shuklin in: http://bugs.gnu.org/18621 * NEWS: Document this. * src/head.c (elseek): Move up. (elide_tail_bytes_pipe, elide_tail_lines_pipe): New arg CURRENT_POS. All uses changed. (elide_tail_bytes_file, elide_tail_lines_file): New arg ST and remove arg SIZE. All uses changed. * src/head.c (elide_tail_bytes_file): * src/od.c (skip): Avoid optimization for /sys files, where st_size is bogus and st_size == st_blksize. Don't report error at EOF when not optimizing. * src/head.c, src/od.c, src/tail.c: Include "stat-size.h". * src/split.c (input_file_size): New function. (bytes_split, lines_chunk_split, bytes_chunk_extract): New arg INITIAL_READ. All uses changed. Use it to double-check st_size. * src/tac.c (tac_seekable): New arg FILE_POS. All uses changed. (copy_to_temp): Return size of temp file. All uses changed. * src/tac.c (tac_seekable): * src/tail.c (tail_bytes): * src/wc.c (wc): Don't trust st_size; double-check by reading. * src/wc.c (wc): New arg CURRENT_POS. All uses changed. * tests/local.mk (all_tests): Add tests/misc/wc-proc.sh, tests/misc/od-j.sh, tests/tail-2/tail-c.sh. * tests/misc/head-c.sh: * tests/misc/tac-2-nonseekable.sh: * tests/split/b-chunk.sh: Add tests for problems with /proc and /sys files. * tests/misc/od-j.sh, tests/misc/wc-proc.sh, tests/tail-2/tail-c.sh: New files. --- tests/local.mk | 3 +++ tests/misc/head-c.sh | 12 ++++++++++++ tests/misc/od-j.sh | 39 +++++++++++++++++++++++++++++++++++++++ tests/misc/tac-2-nonseekable.sh | 14 +++++++++++++- tests/misc/wc-proc.sh | 32 ++++++++++++++++++++++++++++++++ tests/split/b-chunk.sh | 39 ++++++++++++++++++++++++--------------- tests/tail-2/tail-c.sh | 35 +++++++++++++++++++++++++++++++++++ 7 files changed, 158 insertions(+), 16 deletions(-) create mode 100755 tests/misc/od-j.sh create mode 100755 tests/misc/wc-proc.sh create mode 100755 tests/tail-2/tail-c.sh (limited to 'tests') diff --git a/tests/local.mk b/tests/local.mk index 8498acbbe..e01f4d830 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -256,6 +256,7 @@ all_tests = \ tests/misc/wc-files0-from.pl \ tests/misc/wc-files0.sh \ tests/misc/wc-parallel.sh \ + tests/misc/wc-proc.sh \ tests/misc/cat-proc.sh \ tests/misc/cat-buf.sh \ tests/misc/cat-self.sh \ @@ -295,6 +296,7 @@ all_tests = \ tests/misc/nproc-positive.sh \ tests/misc/numfmt.pl \ tests/misc/od-N.sh \ + tests/misc/od-j.sh \ tests/misc/od-multiple-t.sh \ tests/misc/od-x8.sh \ tests/misc/paste.pl \ @@ -399,6 +401,7 @@ all_tests = \ tests/tail-2/wait.sh \ tests/tail-2/retry.sh \ tests/tail-2/symlink.sh \ + tests/tail-2/tail-c.sh \ tests/chmod/c-option.sh \ tests/chmod/equal-x.sh \ tests/chmod/equals.sh \ diff --git a/tests/misc/head-c.sh b/tests/misc/head-c.sh index d6433d0dd..807e96544 100755 --- a/tests/misc/head-c.sh +++ b/tests/misc/head-c.sh @@ -42,4 +42,16 @@ esac # based on the value passed to -c (ulimit -v 20000; head --bytes=-$SSIZE_MAX < /dev/null) || fail=1 +# Make sure it works on funny files in /proc and /sys. + +for file in /proc/cpuinfo /sys/kernel/profiling; do + if test -r $file; then + cp -f $file copy && + head -c -1 copy > exp1 || framework_failure_ + + head -c -1 $file > out1 || fail=1 + compare exp1 out1 || fail=1 + fi +done + Exit $fail diff --git a/tests/misc/od-j.sh b/tests/misc/od-j.sh new file mode 100755 index 000000000..a40a99ff7 --- /dev/null +++ b/tests/misc/od-j.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# Verify that 'od -j N' skips N bytes of input. + +# Copyright 2014 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 . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ od + +for file in ${srcdir=.}/tests/init.sh /proc/version /sys/kernel/profiling; do + test -r $file || continue + + cp -f $file copy && + bytes=$(wc -c < copy) || framework_failure_ + + od -An $file > exp || fail=1 + od -An -j $bytes $file $file > out || fail=1 + compare out exp || fail=1 + + od -An -j 4096 copy copy > exp1 2> experr1; expstatus=$? + od -An -j 4096 $file $file > out1 2> err1; status=$? + test $status -eq $expstatus || fail=1 + compare out1 exp1 || fail=1 + compare err1 experr1 || fail=1 +done + +Exit $fail diff --git a/tests/misc/tac-2-nonseekable.sh b/tests/misc/tac-2-nonseekable.sh index c27694c17..a4a35ab9d 100755 --- a/tests/misc/tac-2-nonseekable.sh +++ b/tests/misc/tac-2-nonseekable.sh @@ -1,5 +1,5 @@ #!/bin/sh -# ensure that tac works with two or more non-seekable inputs +# ensure that tac works with non-seekable or quasi-seekable inputs # Copyright (C) 2011-2014 Free Software Foundation, Inc. @@ -24,4 +24,16 @@ echo x > exp || fail=1 compare exp out || fail=1 compare /dev/null err || fail=1 +# Make sure it works on funny files in /proc and /sys. + +for file in /proc/version /sys/kernel/profiling; do + if test -r $file; then + cp -f $file copy && + tac copy > exp1 || framework_failure_ + + tac $file > out1 || fail=1 + compare exp1 out1 || fail=1 + fi +done + Exit $fail diff --git a/tests/misc/wc-proc.sh b/tests/misc/wc-proc.sh new file mode 100755 index 000000000..828160d4f --- /dev/null +++ b/tests/misc/wc-proc.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Test wc on /proc and /sys files. + +# Copyright 2014 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 . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ wc + +for file in /proc/version /sys/kernel/profiling; do + if test -r $file; then + cp -f $file copy && + wc -c < copy > exp1 || framework_failure_ + + wc -c < $file > out1 || fail=1 + compare exp1 out1 || fail=1 + fi +done + +Exit $fail diff --git a/tests/split/b-chunk.sh b/tests/split/b-chunk.sh index 86f95a057..fefa0900d 100755 --- a/tests/split/b-chunk.sh +++ b/tests/split/b-chunk.sh @@ -31,20 +31,29 @@ stat x?? 2>/dev/null && fail=1 printf '1\n2\n3\n4\n5\n' > in || framework_failure_ -split -n 3 in > out || fail=1 -split -n 1/3 in > b1 || fail=1 -split -n 2/3 in > b2 || fail=1 -split -n 3/3 in > b3 || fail=1 -printf '1\n2' > exp-1 -printf '\n3\n' > exp-2 -printf '4\n5\n' > exp-3 - -compare exp-1 xaa || fail=1 -compare exp-2 xab || fail=1 -compare exp-3 xac || fail=1 -compare exp-1 b1 || fail=1 -compare exp-2 b2 || fail=1 -compare exp-3 b3 || fail=1 -test -f xad && fail=1 +for file in in /proc/version /sys/kernel/profiling; do + split -n 3 $file > out || fail=1 + split -n 1/3 $file > b1 || fail=1 + split -n 2/3 $file > b2 || fail=1 + split -n 3/3 $file > b3 || fail=1 + + case $file in + in) + printf '1\n2' > exp-1 + printf '\n3\n' > exp-2 + printf '4\n5\n' > exp-3 + + compare exp-1 xaa || fail=1 + compare exp-2 xab || fail=1 + compare exp-3 xac || fail=1 + ;; + esac + + compare xaa b1 || fail=1 + compare xab b2 || fail=1 + compare xac b3 || fail=1 + cat xaa xab xac | compare - $file || fail=1 + test -f xad && fail=1 +done Exit $fail diff --git a/tests/tail-2/tail-c.sh b/tests/tail-2/tail-c.sh new file mode 100755 index 000000000..cdbaa46a9 --- /dev/null +++ b/tests/tail-2/tail-c.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# exercise tail -c + +# Copyright 2014 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 . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ tail +require_ulimit_v_ + +# Make sure it works on funny files in /proc and /sys. + +for file in /proc/version /sys/kernel/profiling; do + if test -r $file; then + cp -f $file copy && + tail -c -1 copy > exp1 || framework_failure_ + + tail -c -1 $file > out1 || fail=1 + compare exp1 out1 || fail=1 + fi +done + +Exit $fail -- cgit v1.2.3-54-g00ecf