1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-04-21 03:12:48 +02:00
Files
coreutils/tests/ls/stat-vs-dirent

61 lines
2.1 KiB
Plaintext
Raw Normal View History

2006-05-06 15:27:38 +00:00
#!/bin/sh
# Ensure that d_ino (from ls -di) and st_ino (from stat --format=%i) match.
# Copyright (C) 2006-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_ ls
2006-05-06 15:27:38 +00:00
root_dev_ino=`stat --format=%d-%i /`
t=`pwd`
while :; do
ls -i1 "$t" > tmp
if test $? = 0; then
# Extract the inode number from the first line of output from ls -i1.
# This value comes from dirent.d_ino, on systems with d_ino support.
d_ino=`sed -n '1s/^ *\([0-9][0-9]*\) .*/\1/p;q' tmp`
# Extract the name of the corresponding directory entry.
file=`sed -n '1s/^ *[0-9][0-9]* *//p;q' tmp`
# Get its inode number (stat.st_ino) via stat(1)'s call to lstat.
st_ino=`stat --format=%i "$t/$file"`
# Make sure that they are the same.
# We know from experience that there may be mismatches on some
# buggy file systems, at mount points.
# Note that when a directory contains only entries whose names
# start with ".", d_ino and file will both be empty. In that case,
# skip the test.
if test -n "$d_ino" && test "$d_ino" != "$st_ino"; then
echo "$0: test failed: $t/$file: d_ino($d_ino) != st_ino($st_ino)
This may indicate a flaw in your kernel or file system implementation.
The flaw isn't serious for coreutils, but it might break other tools,
so you should report it to your operating system vendor." 1>&2
ls -i: print consistent inode numbers also for mount points On most unix- and linux-based kernels, ls -i DIR_CONTAINING_MOUNT_POINT would print the wrong inode number for any entry that is a mount point. It would do that by relying on readdir's dirent.d_ino values, while most readdir implementations return the inode number of the underlying, inaccessible directory. Thus, it is not consistent with what you'd get when applying stat to the same entry. This bug led to surprising results like "ls -i" and "ls -i --color" printing different numbers (ls must usually "stat" a file to colorize its name). This change makes it so that on offending systems, ls must stat non-command-line-arguments for which otherwise it would be able to use "for free" dirent.d_ino values. Regardless of this change, ls is already required to stat every command-line argument. Note: versions of GNU ls prior to coreutils-6.0 did not perform the invalid optimization, and hence always printed correct inode numbers. Thus, for the sake of correctness, ls -i is forgoing the readdir optimization, for any kernel (including linux!) with POSIX-nonconforming readdir. Note that currently, only Cygwin has been agile enough to conform. * src/ls.c (RELIABLE_D_INO): Define. (print_dir): Use it. For plenty of discussion, see this long thread: http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14020 This bug was introduced by the 2006-02-26 commit, 33eb3efe: "In ls, avoid calling stat for --inode (-i), when possible." * tests/ls/readdir-mountpoint-inode: New test. * tests/Makefile.am (TESTS): Add it. * tests/ls/stat-vs-dirent: Don't suppress failure of this test, now that ls -i is fixed. Though note that it doesn't test well, since it compares only the always-stat'd command-line arguments. * NEWS (Bug fixes): Mention it.
2008-07-02 18:01:43 +02:00
fail=1
2006-05-06 15:27:38 +00:00
break
fi
fi
t=`(cd "$t/.."; pwd)`
dev_ino=`stat --format=%d-%i "$t"`
test $dev_ino = $root_dev_ino && break
done
Exit $fail