>From ef9650170f795be41223c8887258a1c596ecc162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Sun, 26 Jun 2016 20:58:41 +0100 Subject: [PATCH 1/2] all: update gnulib submodule and tests/init.sh to latest * gnulib: Update to latest. * NEWS: Specifically mention the fts readdir() fix and reindent to standard indentation. * tests/init.sh: Update from gnulib. --- NEWS | 60 ++++++++++++++++++++++++++++++++--------------------------- gnulib | 2 +- tests/init.sh | 31 ++++++++++++++++-------------- 3 files changed, 51 insertions(+), 42 deletions(-) diff --git a/NEWS b/NEWS index b6c5c06..bfaf239 100644 --- a/NEWS +++ b/NEWS @@ -4,46 +4,52 @@ GNU coreutils NEWS -*- outline -*- ** Bug fixes - cp, mv, and install no longer run into undefined behavior when - handling ACLs on Cygwin and Solaris platforms. [bug introduced in - coreutils-8.24] + cp, mv, and install no longer run into undefined behavior when + handling ACLs on Cygwin and Solaris platforms. [bug introduced in + coreutils-8.24] - date, du, ls, and pr no longer mishandle time zone abbreviations on - System V style platforms where this information is available only - in the global variable 'tzname'. [bug introduced in coreutils-8.24] + chcon, chgrp, chmod, chown, du, and rm, or specifically utilities + using the FTS interface, now diagnose failures returned by readdir(). + [this bug was inherent in the use of fts: thus, for rm the bug was + introduced in coreutils-8.0. du, chmod, chgrp and chown started using + fts in 6.0. chcon was added in coreutils-6.9.91 with fts support. ] - nl now resets numbering for each page section rather than just for each page. - [This bug was present in "the beginning".] + date, du, ls, and pr no longer mishandle time zone abbreviations on + System V style platforms where this information is available only + in the global variable 'tzname'. [bug introduced in coreutils-8.24] - stty --help no longer outputs extraneous gettext header lines - for translated languages. [bug introduced in coreutils-8.24] + nl now resets numbering for each page section rather than just for each page. + [This bug was present in "the beginning".] - seq now immediately exits upon write errors. - [This bug was present in "the beginning".] + stty --help no longer outputs extraneous gettext header lines + for translated languages. [bug introduced in coreutils-8.24] - yes now handles short writes, rather than assuming all writes complete. - [bug introduced in coreutils-8.24] + seq now immediately exits upon write errors. + [This bug was present in "the beginning".] + + yes now handles short writes, rather than assuming all writes complete. + [bug introduced in coreutils-8.24] ** Changes in behavior - seq no longer accepts 0 value as increment, and now also rejects NaN - values for any argument. + seq no longer accepts 0 value as increment, and now also rejects NaN + values for any argument. - stat now outputs nanosecond information for time stamps even if - they are out of localtime range. + stat now outputs nanosecond information for time stamps even if + they are out of localtime range. - sort, tail, and uniq now support traditional usage like 'sort +2' - and 'tail +10' on systems conforming to POSIX 1003.1-2008 and later. - The 2008 edition of POSIX dropped the requirement that arguments - like '+2' must be treated as file names. + sort, tail, and uniq now support traditional usage like 'sort +2' + and 'tail +10' on systems conforming to POSIX 1003.1-2008 and later. + The 2008 edition of POSIX dropped the requirement that arguments + like '+2' must be treated as file names. ** Improvements - stat and tail now know about "prl_fs" (a parallels file system), - "m1fs" (a Plexistor file system), "wslfs" (Windows Subsystem for Linux), - and "smb2". stat -f --format=%T now reports the file system type, and - tail -f uses polling for "prl_fs" and "smb2", inotify for "m1fs", - and attempts inotify for "wslfs". + stat and tail now know about "prl_fs" (a parallels file system), + "m1fs" (a Plexistor file system), "wslfs" (Windows Subsystem for Linux), + and "smb2". stat -f --format=%T now reports the file system type, and + tail -f uses polling for "prl_fs" and "smb2", inotify for "m1fs", + and attempts inotify for "wslfs". * Noteworthy changes in release 8.25 (2016-01-20) [stable] diff --git a/gnulib b/gnulib index 841c4fa..6835fc4 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 841c4fa800b4c5c930c3350e5a9a164b204a79c8 +Subproject commit 6835fc458f30b94f15d69c35a79cbc2dfabe2d06 diff --git a/tests/init.sh b/tests/init.sh index ee08022..97e4e4b 100755 --- a/tests/init.sh +++ b/tests/init.sh @@ -308,13 +308,19 @@ if diff_out_=`exec 2>/dev/null; diff -u "$0" "$0" < /dev/null` \ fi } fi -elif diff_out_=`exec 2>/dev/null; diff -c "$0" "$0" < /dev/null`; then +elif + for diff_opt_ in -U3 -c '' no; do + test "$diff_opt_" = no && break + diff_out_=`exec 2>/dev/null; diff $diff_opt_ "$0" "$0" diff.out; then + if diff $diff_opt_ "$@" > diff.out; then # No differences were found, but AIX and HP-UX 'diff' produce output # "No differences encountered" or "There are no differences between the # files.". Hide this output. @@ -466,7 +472,6 @@ setup_ () fi initial_cwd_=$PWD - fail=0 pfx_=`testdir_prefix_` test_dir_=`mktempd_ "$initial_cwd_" "$pfx_-$ME_.XXXX"` \ @@ -550,8 +555,9 @@ mktempd_ () # Disallow any trailing slash on specified destdir: # it would subvert the post-mktemp "case"-based destdir test. case $destdir_ in - /) ;; + / | //) destdir_slash_=$destdir;; */) fail_ "invalid destination dir: remove trailing slash(es)";; + *) destdir_slash_=$destdir_/;; esac case $template_ in @@ -561,20 +567,17 @@ mktempd_ () esac # First, try to use mktemp. - d=`unset TMPDIR; { mktemp -d -t -p "$destdir_" "$template_"; } 2>/dev/null` \ - || fail=1 + d=`unset TMPDIR; { mktemp -d -t -p "$destdir_" "$template_"; } 2>/dev/null` && # The resulting name must be in the specified directory. - case $d in "$destdir_"*);; *) fail=1;; esac + case $d in "$destdir_slash_"*) :;; *) false;; esac && # It must have created the directory. - test -d "$d" || fail=1 + test -d "$d" && # It must have 0700 permissions. Handle sticky "S" bits. - perms=`ls -dgo "$d" 2>/dev/null|tr S -` || fail=1 - case $perms in drwx------*) ;; *) fail=1;; esac - - test $fail = 0 && { + perms=`ls -dgo "$d" 2>/dev/null` && + case $perms in drwx--[-S]---*) :;; *) false;; esac && { echo "$d" return } @@ -593,7 +596,7 @@ mktempd_ () i_=1 while :; do X_=`rand_bytes_ $nx_` - candidate_dir_="$destdir_/$base_template_$X_" + candidate_dir_="$destdir_slash_$base_template_$X_" err_=`mkdir -m 0700 "$candidate_dir_" 2>&1` \ && { echo "$candidate_dir_"; return; } test $MAX_TRIES_ -le $i_ && break; -- 2.5.5 >From e84298a2589918ffe74a71d91fcf5271eacb3708 Mon Sep 17 00:00:00 2001 From: Peter Benie Date: Sun, 26 Jun 2016 19:07:45 +0100 Subject: [PATCH 2/2] tests: verify that fts diagnoses readdir() failures * tests/rm/rm-readdir-fail.sh: A new test to simulate readdir() failing immediately or after returning a few entries, and verifying that rm does the appropriate thing. This was initially reported at: http://bugzilla.opensuse.org/show_bug.cgi?id=984910 where it was mentioned that readdir() may fail when an NFS server has a poor readdir cookie implementation. --- tests/local.mk | 1 + tests/rm/rm-readdir-fail.sh | 108 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100755 tests/rm/rm-readdir-fail.sh diff --git a/tests/local.mk b/tests/local.mk index d3afb6e..3032bda 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -223,6 +223,7 @@ all_tests = \ tests/rm/unreadable.pl \ tests/rm/v-slash.sh \ tests/rm/many-dir-entries-vs-OOM.sh \ + tests/rm/rm-readdir-fail.sh \ tests/chgrp/default-no-deref.sh \ tests/chgrp/deref.sh \ tests/chgrp/no-x.sh \ diff --git a/tests/rm/rm-readdir-fail.sh b/tests/rm/rm-readdir-fail.sh new file mode 100755 index 0000000..20ea50e --- /dev/null +++ b/tests/rm/rm-readdir-fail.sh @@ -0,0 +1,108 @@ +#!/bin/sh +# Test rm's behaviour when the directory cannot be read. +# This test is skipped on systems that lack LD_PRELOAD support. + +# Copyright (C) 2016 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_ rm +require_gcc_shared_ + +mkdir -p dir/notempty || framework_failure_ + +# Simulate "readdir" failure. +cat > k.c <<\EOF || framework_failure_ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +struct dirent *readdir (DIR *dirp) +{ + struct dirent *(*real_readdir)(DIR *dirp) = dlsym (RTLD_NEXT, "readdir"); + if (! real_readdir) + { + fprintf (stderr, "Failed to find readdir()\n"); + errno = ESRCH; + return NULL; + } + struct dirent* d = real_readdir (dirp); + if (! d) + { + fprintf (stderr, "Failed to get dirent\n"); + errno = ENOENT; + return NULL; + } + + /* Flag that LD_PRELOAD and above functions work. */ + static int done = 0; + if (! done) + { + fclose (fopen ("preloaded", "w")); + done++; + } + + /* Return some entries to trigger partial read failure, + ensuring we don't return ignored '.' or '..' */ + char const *readdir_partial = getenv ("READDIR_PARTIAL"); + if (readdir_partial && *readdir_partial && done <= 3) + { + done++; + d->d_name[0]='0'+done; d->d_name[1]='\0'; +#ifdef _DIRENT_HAVE_D_NAMLEN + _D_EXACT_NAMELEN(d)=2; +#endif + errno = 0; + return d; + }; + + /* Fail. */ + errno = ENOENT; + return NULL; +} + +struct dirent64 *readdir64 (DIR *dirp) +{ + return (struct dirent64 *) readdir (dirp); +} +EOF + +# Then compile/link it: +gcc_shared_ k.c k.so \ + || framework_failure_ 'failed to build shared library' + +# Test if LD_PRELOAD works: +export READDIR_PARTIAL +for READDIR_PARTIAL in '' '1'; do + (LD_PRELOAD=$LD_PRELOAD:./k.so returns_ 1 rm -Rf dir 2>>err) || fail=1 +done +test -f preloaded || + skip_ "internal test failure: maybe LD_PRELOAD doesn't work?" + +# First case is failure to read any items from dir, then assume empty. +# Generally that will be diagnosed when rm tries to rmdir(). +# Second case is more general error where we fail immediately +# (with ENOENT in this case but it could be anything). +cat < exp +rm: cannot remove 'dir': Directory not empty +rm: traversal failed: dir: No such file or directory +EOF + +compare exp err || fail=1 + +Exit $fail -- 2.5.5