diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 16:58:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 16:58:41 +0000 |
commit | e1908ae95dd4c9d19ee4dfabfc8bf8a7f85943fe (patch) | |
tree | f5cc731bedcac0fb7fe14d952e4581e749f8bb87 /tests/ls | |
parent | Initial commit. (diff) | |
download | coreutils-e1908ae95dd4c9d19ee4dfabfc8bf8a7f85943fe.tar.xz coreutils-e1908ae95dd4c9d19ee4dfabfc8bf8a7f85943fe.zip |
Adding upstream version 9.4.upstream/9.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ls')
49 files changed, 3079 insertions, 0 deletions
diff --git a/tests/ls/a-option.sh b/tests/ls/a-option.sh new file mode 100755 index 0000000..c154666 --- /dev/null +++ b/tests/ls/a-option.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# exercise the -a option + +# Copyright 2018-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir d || framework_failure_ + +ls -aA d >out || framework_failure_ +compare /dev/null out || fail=1 + +Exit $fail diff --git a/tests/ls/abmon-align.sh b/tests/ls/abmon-align.sh new file mode 100755 index 0000000..73308dc --- /dev/null +++ b/tests/ls/abmon-align.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# Ensure ls output is aligned when using abbreviated months from the locale + +# Copyright (C) 2009-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mid_month="$(date +%Y-%m-15)" || framework_failure_ +for mon in $(seq -w 12); do + touch -d"$mid_month +$mon month" $mon.ts || framework_failure_ +done + + +# Note some of the following locales may be missing but if so +# we should fail back to the C locale which should be aligned + +for format in "%b" "[%b" "%b]" "[%b]"; do + for LOC in C gv_GB ga_IE fi_FI.utf8 zh_CN ar_SY $LOCALE_FR_UTF8; do + # The sed usage here is slightly different from the original, + # removing the \(.*\), to avoid triggering misbehavior in at least + # GNU sed 4.2 (possibly miscompiled) on Mac OS X (Darwin 9.8.0). + months="$( + LC_ALL=$LOC TIME_STYLE=+"$format" ls -lgG *.ts | + LC_ALL=C sed 's/.\{15\}//;s/ ..\.ts$//;s/ /./g')" + n_widths=$(echo "$months" | + while read mon; do echo "$mon" | LC_ALL=$LOC wc -L; done | + uniq | wc -l + ) + n_dupes=$(echo "$months" | sort | uniq -d | wc -l) + test "$n_widths" = "1" || { fail=1; break 2; } + test "$n_dupes" = "0" || { fail=1; break 2; } + done +done +if test "$fail" = "1"; then + echo "misalignment or ambiguous output in $LOC locale:" + LC_ALL=$LOC TIME_STYLE=+%b ls -lgG *.ts +fi + +Exit $fail diff --git a/tests/ls/birthtime.sh b/tests/ls/birthtime.sh new file mode 100755 index 0000000..7f6347f --- /dev/null +++ b/tests/ls/birthtime.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# ensure that ls attempts birthtime access + +# Copyright (C) 2020-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# ls should not fail, even if birth time not available +touch a || framework_failure_ +ls --time=birth -l a || fail=1 +ls --time=creation -t a || fail=1 + +Exit $fail diff --git a/tests/ls/block-size.sh b/tests/ls/block-size.sh new file mode 100755 index 0000000..3dfd5fe --- /dev/null +++ b/tests/ls/block-size.sh @@ -0,0 +1,186 @@ +#!/bin/sh +# Exercise ls --block-size and related options. + +# Copyright (C) 2011-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +TZ=UTC0 +export TZ + +mkdir sub +cd sub + +for size in 1024 4096 262144; do + echo foo | dd conv=sync bs=$size >file$size || fail=1 +done +touch -d '2001-01-01 00:00' file* || fail=1 + +size_etc='s/[^ ]* *[^ ]* *//' + +ls -og * | sed "$size_etc" >../out || fail=1 +POSIXLY_CORRECT=1 ls -og * | sed "$size_etc" >>../out || fail=1 +POSIXLY_CORRECT=1 ls -k -og * | sed "$size_etc" >>../out || fail=1 + +for var in BLOCKSIZE BLOCK_SIZE LS_BLOCK_SIZE; do + for blocksize in 1 512 1K 1KiB; do + (eval $var=$blocksize && export $var && + echo "x x # $var=$blocksize" && + ls -og * && + ls -og -k * && + ls -og -k --block-size=$blocksize * + ) | sed "$size_etc" >>../out || fail=1 + done +done + +cd .. + +cat >exp <<'EOF' +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +# BLOCKSIZE=1 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +# BLOCKSIZE=512 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +2 Jan 1 2001 file1024 +512 Jan 1 2001 file262144 +8 Jan 1 2001 file4096 +# BLOCKSIZE=1K +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +# BLOCKSIZE=1KiB +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +# BLOCK_SIZE=1 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +# BLOCK_SIZE=512 +2 Jan 1 2001 file1024 +512 Jan 1 2001 file262144 +8 Jan 1 2001 file4096 +2 Jan 1 2001 file1024 +512 Jan 1 2001 file262144 +8 Jan 1 2001 file4096 +2 Jan 1 2001 file1024 +512 Jan 1 2001 file262144 +8 Jan 1 2001 file4096 +# BLOCK_SIZE=1K +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +# BLOCK_SIZE=1KiB +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +# LS_BLOCK_SIZE=1 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +1024 Jan 1 2001 file1024 +262144 Jan 1 2001 file262144 +4096 Jan 1 2001 file4096 +# LS_BLOCK_SIZE=512 +2 Jan 1 2001 file1024 +512 Jan 1 2001 file262144 +8 Jan 1 2001 file4096 +2 Jan 1 2001 file1024 +512 Jan 1 2001 file262144 +8 Jan 1 2001 file4096 +2 Jan 1 2001 file1024 +512 Jan 1 2001 file262144 +8 Jan 1 2001 file4096 +# LS_BLOCK_SIZE=1K +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +# LS_BLOCK_SIZE=1KiB +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +1 Jan 1 2001 file1024 +256 Jan 1 2001 file262144 +4 Jan 1 2001 file4096 +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/capability.sh b/tests/ls/capability.sh new file mode 100755 index 0000000..0ccceda --- /dev/null +++ b/tests/ls/capability.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# Ensure "ls --color" properly colors name of file with capability. + +# Copyright (C) 2008-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls printf +require_root_ + +grep '^#define HAVE_CAP 1' $CONFIG_HEADER > /dev/null \ + || skip_ "configured without libcap support" + +(setcap --help) 2>&1 |grep 'usage: setcap' > /dev/null \ + || skip_ "setcap utility not found" + +# Don't let a different umask perturb the results. +umask 22 + +# We create 2 files of the same name as +# before coreutils 8.1 only the name rather than +# the full path was used to read the capabilities +# thus giving false positives and negatives. +mkdir test test/dir +cd test +touch cap_pos dir/cap_pos dir/cap_neg +for file in cap_pos dir/cap_neg; do + setcap 'cap_net_bind_service=ep' $file || + skip_ "setcap doesn't work" +done + +code='30;41' +# Note we explicitly disable "executable" coloring +# so that capability coloring is not dependent on it, +# as was the case before coreutils 8.1 +for ex in '' ex=:; do + LS_COLORS="di=:${ex}ca=$code" \ + ls --color=always cap_pos dir > out || fail=1 + + env printf "\ +\e[0m\e[${code}mcap_pos\e[0m + +dir: +\e[${code}mcap_neg\e[0m +cap_pos +" > out_ok || framework_failure_ + + compare out out_ok || fail=1 +done + +Exit $fail diff --git a/tests/ls/classify.sh b/tests/ls/classify.sh new file mode 100755 index 0000000..8645ab5 --- /dev/null +++ b/tests/ls/classify.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# Test --classify processing + +# Copyright (C) 2020-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir testdir || framework_failure_ +cd testdir || framework_failure_ +mkdir dir || framework_failure_ +touch regular executable || framework_failure_ +chmod a+x executable || framework_failure_ +ln -s regular slink-reg || framework_failure_ +ln -s dir slink-dir || framework_failure_ +ln -s nowhere slink-dangle || framework_failure_ +mknod block b 20 20 2> /dev/null && block="block +" +mknod char c 10 10 2> /dev/null && char="char +" +mkfifo_or_skip_ fifo +cd .. + +cat <<EOF > exp +$block${char}dir/ +executable* +fifo| +regular +slink-dangle@ +slink-dir@ +slink-reg@ +EOF +sed 's/[*/@|]//' exp > exp2 || framework_failure_ + +ls --classify testdir > out || fail=1 +ls --classify=always testdir > out2 || fail=1 +ls --classify=auto testdir > out3 || fail=1 +ls --classify=never testdir > out4 || fail=1 + +compare exp out || fail=1 + +compare exp out2 || fail=1 + +compare exp2 out3 || fail=1 + +compare exp2 out4 || fail=1 + +returns_ 1 ls --classify=invalid || fail=1 + +Exit $fail diff --git a/tests/ls/color-clear-to-eol.sh b/tests/ls/color-clear-to-eol.sh new file mode 100755 index 0000000..dc4bcd2 --- /dev/null +++ b/tests/ls/color-clear-to-eol.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# ensure that ls --color works well when a colored name is wrapped + +# Copyright (C) 2009-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +long_name=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.foo +touch $long_name || framework_failure_ + +e='\33' +color_code='0;31;42' +c_pre="$e[0m$e[${color_code}m" +c_post="$e[0m$e[K\n" +printf "$c_pre$long_name$c_post\n" > exp || framework_failure_ + +env TERM=xterm COLUMNS=80 LS_COLORS="*.foo=$color_code" TIME_STYLE=+T \ + ls -og --color=always $long_name > out || fail=1 + +# Append a newline, to accommodate less-capable versions of sed. +echo >> out || framework_failure_ + +sed 's/.*T //' out > k && mv k out + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/color-dtype-dir.sh b/tests/ls/color-dtype-dir.sh new file mode 100755 index 0000000..d51cbaf --- /dev/null +++ b/tests/ls/color-dtype-dir.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# Ensure "ls --color" properly colors other-writable and sticky directories. +# Before coreutils-6.2, this test would fail, coloring all three +# directories the same as the first one -- but only on a file system +# with dirent.d_type support. + +# Copyright (C) 2006-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# Don't let a different umask perturb the results. +umask 22 + +mkdir d other-writable sticky || framework_failure_ +chmod o+w other-writable || framework_failure_ +chmod o+t sticky || framework_failure_ + + +TERM=xterm ls --color=always > out || fail=1 +cat -A out > o1 || framework_failure_ +mv o1 out || framework_failure_ + +cat <<\EOF > exp || framework_failure_ +^[[0m^[[01;34md^[[0m$ +^[[34;42mother-writable^[[0m$ +out$ +^[[37;44msticky^[[0m$ +EOF + +compare exp out || fail=1 + +rm exp || framework_failure_ + +# Turn off colors for other-writable dirs and ensure +# we fall back to the color for standard directories. + +LS_COLORS="ow=:" ls --color=always > out || fail=1 +cat -A out > o1 || fail=1 +mv o1 out || fail=1 + +cat <<\EOF > exp || framework_failure_ +^[[0m^[[01;34md^[[0m$ +^[[01;34mother-writable^[[0m$ +out$ +^[[37;44msticky^[[0m$ +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/color-ext.sh b/tests/ls/color-ext.sh new file mode 100755 index 0000000..dbc0d0a --- /dev/null +++ b/tests/ls/color-ext.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# Ensure "ls --color" properly colors file name extensions. + +# Copyright (C) 2018-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +working_umask_or_skip_ + +touch img1.jpg IMG2.JPG img3.JpG file1.z file2.Z || framework_failure_ +code_jpg='01;35' +code_JPG='01;35;46' +code_z='01;31' +c0=$(printf '\033[0m') +c_jpg=$(printf '\033[%sm' $code_jpg) +c_JPG=$(printf '\033[%sm' $code_JPG) +c_z=$(printf '\033[%sm' $code_z) + +# Case insensitive extensions +LS_COLORS="*.jpg=$code_jpg:*.Z=$code_z" ls -U1 --color=always \ + img1.jpg IMG2.JPG file1.z file2.Z > out || fail=1 +printf "$c0\ +${c_jpg}img1.jpg$c0 +${c_jpg}IMG2.JPG$c0 +${c_z}file1.z$c0 +${c_z}file2.Z$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# Case sensitive extensions +LS_COLORS="*.jpg=$code_jpg:*.JPG=$code_JPG" ls -U1 --color=always \ + img1.jpg IMG2.JPG img3.JpG > out || fail=1 +printf "$c0\ +${c_jpg}img1.jpg$c0 +${c_JPG}IMG2.JPG$c0 +img3.JpG +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# Case insensitive extensions (due to same sequences) +LS_COLORS="*.jpg=$code_jpg:*.JPG=$code_jpg" ls -U1 --color=always \ + img1.jpg IMG2.JPG img3.JpG > out || fail=1 +printf "$c0\ +${c_jpg}img1.jpg$c0 +${c_jpg}IMG2.JPG$c0 +${c_jpg}img3.JpG$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# Case insensitive extensions (due to same sequences (after ignored sequences)) +# Note later entries in LS_COLORS take precedence. +LS_COLORS="*.jpg=$code_jpg:*.jpg=$code_JPG:*.JPG=$code_JPG" \ + ls -U1 --color=always img1.jpg IMG2.JPG img3.JpG > out || fail=1 +printf "$c0\ +${c_JPG}img1.jpg$c0 +${c_JPG}IMG2.JPG$c0 +${c_JPG}img3.JpG$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# Case sensitive extensions (due to diff sequences (after ignored sequences)) +# Note later entries in LS_COLORS take precedence. +LS_COLORS="*.jpg=$code_JPG:*.jpg=$code_jpg:*.JPG=$code_JPG" \ + ls -U1 --color=always img1.jpg IMG2.JPG img3.JpG > out || fail=1 +printf "$c0\ +${c_jpg}img1.jpg$c0 +${c_JPG}IMG2.JPG$c0 +img3.JpG +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +Exit $fail diff --git a/tests/ls/color-norm.sh b/tests/ls/color-norm.sh new file mode 100755 index 0000000..09b52f3 --- /dev/null +++ b/tests/ls/color-norm.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# Ensure "ls --color" properly colors "normal" text and files. +# I.e., that it uses NORMAL to style non file name output and +# file names with no associated color (unless FILE is also set). + +# Copyright (C) 2010-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# Don't let a different umask perturb the results. +umask 22 + +# Output time as something constant +export TIME_STYLE="+norm" + +# helper to strip ls columns up to "norm" time +qls() { sed 's/-r.*norm/norm/'; } + +touch exe || framework_failure_ +chmod u+x exe || framework_failure_ +touch nocolor || framework_failure_ + +TCOLORS="no=7:ex=01;32" + +# Uncolored file names inherit NORMAL attributes. +LS_COLORS=$TCOLORS ls -gGU --color exe nocolor | qls >> out || fail=1 +LS_COLORS=$TCOLORS ls -xU --color exe nocolor >> out || fail=1 +LS_COLORS=$TCOLORS ls -gGU --color nocolor exe | qls >> out || fail=1 +LS_COLORS=$TCOLORS ls -xU --color nocolor exe >> out || fail=1 + +# NORMAL does not override FILE though +LS_COLORS=$TCOLORS:fi=1 ls -gGU --color nocolor exe | qls >> out || fail=1 + +# Support uncolored ordinary files that do _not_ inherit from NORMAL. +# Note there is a redundant RESET output before a non colored +# file in this case which may be removed in future. +LS_COLORS=$TCOLORS:fi= ls -gGU --color nocolor exe | qls >> out || fail=1 +LS_COLORS=$TCOLORS:fi=0 ls -gGU --color nocolor exe | qls >> out || fail=1 + +# A caveat worth noting is that commas (-m), indicator chars (-F) +# and the "total" line, do not currently use NORMAL attributes +LS_COLORS=$TCOLORS ls -mFU --color nocolor exe >> out || fail=1 + +# Ensure no coloring is done unless enabled +LS_COLORS=$TCOLORS ls -gGU nocolor exe | qls >> out || fail=1 + +cat -A out > out.display || framework_failure_ +mv out.display out || framework_failure_ + +cat <<\EOF > exp || framework_failure_ +^[[0m^[[7mnorm ^[[m^[[01;32mexe^[[0m$ +^[[7mnorm nocolor^[[0m$ +^[[0m^[[7m^[[m^[[01;32mexe^[[0m ^[[7mnocolor^[[0m$ +^[[0m^[[7mnorm nocolor^[[0m$ +^[[7mnorm ^[[m^[[01;32mexe^[[0m$ +^[[0m^[[7mnocolor^[[0m ^[[7m^[[m^[[01;32mexe^[[0m$ +^[[0m^[[7mnorm ^[[m^[[1mnocolor^[[0m$ +^[[7mnorm ^[[m^[[01;32mexe^[[0m$ +^[[0m^[[7mnorm ^[[m^[[mnocolor^[[0m$ +^[[7mnorm ^[[m^[[01;32mexe^[[0m$ +^[[0m^[[7mnorm ^[[m^[[0mnocolor^[[0m$ +^[[7mnorm ^[[m^[[01;32mexe^[[0m$ +^[[0m^[[7mnocolor^[[0m, ^[[7m^[[m^[[01;32mexe^[[0m*$ +norm nocolor$ +norm exe$ +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/color-term.sh b/tests/ls/color-term.sh new file mode 100755 index 0000000..3e5aca0 --- /dev/null +++ b/tests/ls/color-term.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# Ensure "ls --color" doesn't output colors for TERM=dumb + +# Copyright (C) 2014-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# Output time as something constant +export TIME_STYLE="+norm" + +touch exe || framework_failure_ +chmod u+x exe || framework_failure_ + +# output colors +LS_COLORS='' COLORTERM='nonempty' TERM='' ls --color=always exe >> out || fail=1 +LS_COLORS='' COLORTERM='' TERM='xterm' ls --color=always exe >> out || fail=1 + +# Don't output colors +LS_COLORS='' COLORTERM='' TERM='dumb' ls --color=always exe >> out || fail=1 +LS_COLORS='' COLORTERM='' TERM='' ls --color=always exe >> out || fail=1 + +cat -A out > out.display || framework_failure_ +mv out.display out || framework_failure_ + +cat <<\EOF > exp || framework_failure_ +^[[0m^[[01;32mexe^[[0m$ +^[[0m^[[01;32mexe^[[0m$ +exe$ +exe$ +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/dangle.sh b/tests/ls/dangle.sh new file mode 100755 index 0000000..0e59e86 --- /dev/null +++ b/tests/ls/dangle.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# Make sure ls properly handles dangling symlinks vs. ls's -L, -H, options. + +# Copyright (C) 2003-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +LS_MINOR_PROBLEM=1 +LS_FAILURE=2 + +ln -s no-such-file dangle || framework_failure_ +mkdir -p dir/sub || framework_failure_ +ln -s dir slink-to-dir || framework_failure_ +mkdir d || framework_failure_ +ln -s no-such d/dangle || framework_failure_ +printf '? dangle\n' > subdir_Li_exp || framework_failure_ +printf 'total 0\n? dangle\n' > subdir_Ls_exp || framework_failure_ + +# This must exit nonzero. +returns_ $LS_FAILURE ls -L dangle > /dev/null 2>&1 || fail=1 +# So must this. +returns_ $LS_FAILURE ls -H dangle > /dev/null 2>&1 || fail=1 + +# This must exit successfully. +ls dangle >> out || fail=1 + +ls slink-to-dir >> out 2>&1 || fail=1 +ls -H slink-to-dir >> out 2>&1 || fail=1 +ls -L slink-to-dir >> out 2>&1 || fail=1 + +cat <<\EOF > exp +dangle +sub +sub +sub +EOF + +compare exp out || fail=1 + +# Ensure that ls -Li prints "?" as the inode of a dangling symlink. +rm -f out +returns_ $LS_MINOR_PROBLEM ls -Li d > out 2>/dev/null || fail=1 +compare subdir_Li_exp out || fail=1 + +# Ensure that ls -Ls prints "?" as the allocation of a dangling symlink. +rm -f out +returns_ $LS_MINOR_PROBLEM ls -Ls d > out 2>/dev/null || fail=1 +compare subdir_Ls_exp out || fail=1 + +Exit $fail diff --git a/tests/ls/dired.sh b/tests/ls/dired.sh new file mode 100755 index 0000000..150fff2 --- /dev/null +++ b/tests/ls/dired.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# make sure --dired option works + +# Copyright (C) 2001-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir dir || framework_failure_ + + +LC_MESSAGES=C ls -lR --dired dir > out || fail=1 +cat <<EOF > exp + dir: + total 0 +//SUBDIRED// 2 5 +//DIRED-OPTIONS// --quoting-style=literal +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/file-type.sh b/tests/ls/file-type.sh new file mode 100755 index 0000000..1df2074 --- /dev/null +++ b/tests/ls/file-type.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# contrast ls -F, ls -p, and ls --indicator-style=file-type + +# Copyright (C) 2002-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir sub +cd sub +mkdir dir +touch regular executable +chmod a+x executable +ln -s regular slink-reg +ln -s dir slink-dir +ln -s nowhere slink-dangle +mknod block b 20 20 2> /dev/null && block="block +" +mknod char c 10 10 2> /dev/null && char="char +" +mkfifo_or_skip_ fifo +cd .. + + + +ls -F sub > out || fail=1 +cat <<EOF > exp +$block${char}dir/ +executable* +fifo| +regular +slink-dangle@ +slink-dir@ +slink-reg@ +EOF + +sed 's/\*//' exp > exp2 +ls --indicator-style=file-type sub > out2 || fail=1 + +sed 's/[@|]$//' exp2 > exp3 +ls -p sub > out3 || fail=1 + +compare exp out || fail=1 + +compare exp2 out2 || fail=1 + +compare exp3 out3 || fail=1 + +ls --color=auto -F sub > out || fail=1 +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/follow-slink.sh b/tests/ls/follow-slink.sh new file mode 100755 index 0000000..38ee0af --- /dev/null +++ b/tests/ls/follow-slink.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# make sure ls -L always follows symlinks + +# Copyright (C) 2000-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +LS_FAILURE=2 + +# Isolate output files from directory being listed +mkdir dir dir/sub dir1 || framework_failure_ +cd dir || framework_failure_ +ln -s link link || framework_failure_ +ln -s ../../dir1 sub/link-to-dir || framework_failure_ + +# Make sure the symlink was created. +# 'ln -s link link' succeeds, but creates no file on +# systems running some DJGPP-2.03 libc. +ls -F link > /dev/null || framework_failure_ + + +# When explicitly listing a broken link, the command must fail. +returns_ $LS_FAILURE ls -L link 2> /dev/null || fail=1 + +# When encountering a broken link implicitly, Solaris 9 and OpenBSD 3.4 +# list the link, provided no further information about the link needed +# to be printed. Since POSIX does not specify one way or the other, we +# opt for compatibility (this was broken in 5.3.0 through 5.94). +LC_ALL=C ls -L > ../out-L || fail=1 +LC_ALL=C ls -FLR sub > ../out-FLR-sub || fail=1 + +cd .. || fail=1 + +cat <<\EOF > exp-L +link +sub +EOF + +cat <<\EOF > exp-FLR-sub +sub: +link-to-dir/ + +sub/link-to-dir: +EOF + +compare exp-L out-L || fail=1 +compare exp-FLR-sub out-FLR-sub || fail=1 + +Exit $fail diff --git a/tests/ls/getxattr-speedup.sh b/tests/ls/getxattr-speedup.sh new file mode 100755 index 0000000..5665e39 --- /dev/null +++ b/tests/ls/getxattr-speedup.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# Show that we've eliminated most of ls' failing getxattr syscalls, +# regardless of how many files are in a directory we list. +# This test is skipped on systems that lack LD_PRELOAD support; that's fine. +# Similarly, on a system that lacks getxattr altogether, skipping it is fine. + +# Copyright (C) 2012-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +require_gcc_shared_ + +# Replace each getxattr and lgetxattr call with a call to these stubs. +# Count those and write the total number of calls to the file "x" +# via a global destructor. +cat > k.c <<'EOF' || framework_failure_ +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> + +static unsigned long int n_calls; + +static void __attribute__ ((destructor)) +print_call_count (void) +{ + FILE *fp = fopen ("x", "w"); if (!fp) return; + fprintf (fp, "%lu\n", n_calls); fclose (fp); +} + +static ssize_t incr () { ++n_calls; errno = ENOTSUP; return -1; } +ssize_t getxattr (const char *path, const char *name, void *value, size_t size) +{ return incr (); } +ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size) +{ return incr (); } +EOF + +# Then compile/link it: +gcc_shared_ k.c k.so \ + || framework_failure_ 'failed to build shared library' + +# Create a few files: +seq 20 | xargs touch || framework_failure_ + +# Finally, run the test: +LD_PRELOAD=$LD_PRELOAD:./k.so ls --color=always -l . || fail=1 + +test -f x || skip_ "internal test failure: maybe LD_PRELOAD doesn't work?" + +# Ensure that there were no more than 3 *getxattr calls. +n_calls=$(cat x) +test "$n_calls" -le 3 || fail=1 + +Exit $fail diff --git a/tests/ls/group-dirs.sh b/tests/ls/group-dirs.sh new file mode 100755 index 0000000..c13a94e --- /dev/null +++ b/tests/ls/group-dirs.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# test --group-directories-first + +# Copyright (C) 2018-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# Isolate output files from directory being listed +mkdir dir dir/b || framework_failure_ +touch dir/a || framework_failure_ +ln -s b dir/bl || framework_failure_ + +ls --group dir > out || fail=1 +cat <<\EOF > exp +b +bl +a +EOF +compare exp out || fail=1 + +ls --group -d dir/* > out || fail=1 +cat <<\EOF > exp +dir/b +dir/bl +dir/a +EOF +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/hex-option.sh b/tests/ls/hex-option.sh new file mode 100755 index 0000000..2a09309 --- /dev/null +++ b/tests/ls/hex-option.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# accept hex/oct numbers to -w and -T + +# Copyright (C) 2014-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +ls -x -T0x10 -w010 || fail=1 + +Exit $fail diff --git a/tests/ls/hyperlink.sh b/tests/ls/hyperlink.sh new file mode 100755 index 0000000..970e062 --- /dev/null +++ b/tests/ls/hyperlink.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# Test --hyperlink processing + +# Copyright (C) 2017-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# lookup based on first letter +encode() { + printf '%s\n' \ + 'sp%20ace' 'ques%3ftion' 'back%5cslash' 'encoded%253Fquestion' 'testdir' \ + "$1" | + sort -k1,1.1 -s | uniq -w1 -d +} + +ls_encoded() { + ef=$(encode "$1") + echo "$ef" | grep 'dir$' >/dev/null && dir=: || dir='' + printf '\033]8;;file:///%s\a%s\033]8;;\a%s\n' \ + "$ef" "$1" "$dir" +} + +# These could be encoded, so remove from consideration +strip_host_and_path() { + sed 's|file://.*/|file:///|' +} + +mkdir testdir || framework_failure_ +( +cd testdir +ls_encoded "testdir" > ../exp.t || framework_failure_ +for f in 'back\slash' 'encoded%3Fquestion' 'ques?tion' 'sp ace'; do + touch "$f" || framework_failure_ + ls_encoded "$f" >> ../exp.t || framework_failure_ +done +) +ln -s testdir testdirl || framework_failure_ +(cat exp.t && printf '\n' && sed 's/[^\/]testdir/&l/' exp.t) > exp \ + || framework_failure_ +ls --hyper testdir testdirl >out.t || fail=1 +strip_host_and_path <out.t >out || framework_failure_ +compare exp out || fail=1 + +ln -s '/probably_missing' testlink || framework_failure_ +ls -l --hyper testlink > out.t || fail=1 +strip_host_and_path <out.t >out || framework_failure_ +grep 'file:///probably_missing' out || fail=1 + +Exit $fail diff --git a/tests/ls/infloop.sh b/tests/ls/infloop.sh new file mode 100755 index 0000000..d59ba81 --- /dev/null +++ b/tests/ls/infloop.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# show that the following no longer makes ls infloop +# mkdir loop; cd loop; ln -s ../loop sub; ls -RL +# Also ensure ls exits with status = 2 in that case. +# Copyright (C) 2001-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir loop || framework_failure_ +ln -s ../loop loop/sub || framework_failure_ + +cat <<\EOF > exp-out || framework_failure_ +loop: +sub +EOF + +cat <<\EOF > exp-err || framework_failure_ +ls: loop/sub: not listing already-listed directory +EOF + +# Ensure that ls exits with status 2 upon detecting a cycle +returns_ 2 timeout 10 ls -RL loop >out 2>err || fail=1 + +compare exp-err err || fail=1 +compare exp-out out || fail=1 + +Exit $fail diff --git a/tests/ls/inode.sh b/tests/ls/inode.sh new file mode 100755 index 0000000..5060a96 --- /dev/null +++ b/tests/ls/inode.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# Make sure that ls -i works properly on symlinks. + +# Copyright (C) 2003-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +touch f || framework_failure_ +ln -s f slink || framework_failure_ + + +# When listed explicitly: + +set x $(ls -Ci f slink); shift +test $# = 4 || fail=1 +# The inode numbers should differ. +test "$1" != "$3" || fail=1 + +set x $(ls -CLi f slink); shift +test $# = 4 || fail=1 +# With -L, they must be the same. +test "$1" = "$3" || fail=1 + +set x $(ls -CHi f slink); shift +test $# = 4 || fail=1 +# With -H, they must be the same, too, from the command line. +# Note that POSIX says -H must make ls dereference only +# symlinks (specified on the command line) to directories, +# but the historical BSD meaning of -H is to dereference +# any symlink given on the command line. For compatibility GNU ls +# implements the BSD semantics. +test "$1" = "$3" || fail=1 + +# When listed from a directory: + +set x $(ls -Ci); shift +test $# = 4 || fail=1 +# The inode numbers should differ. +test "$1" != "$3" || fail=1 + +set x $(ls -CLi); shift +test $# = 4 || fail=1 +# With -L, they must be the same. +test "$1" = "$3" || fail=1 + +set x $(ls -CHi); shift +test $# = 4 || fail=1 +# With -H, they must be different from inside a directory. +test "$1" != "$3" || fail=1 + +Exit $fail diff --git a/tests/ls/ls-misc.pl b/tests/ls/ls-misc.pl new file mode 100755 index 0000000..f3f09c4 --- /dev/null +++ b/tests/ls/ls-misc.pl @@ -0,0 +1,375 @@ +#!/usr/bin/perl + +# Copyright (C) 1998-2023 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 <https://www.gnu.org/licenses/>. + +use strict; + +(my $ME = $0) =~ s|.*/||; +my $prog = 'ls'; + +# Turn off localization of executable's output. +@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + +my $saved_ls_colors; + +sub push_ls_colors($) +{ + $saved_ls_colors = $ENV{LS_COLORS} || ''; + $ENV{LS_COLORS} = $_[0]; +} + +sub restore_ls_colors() +{ + $ENV{LS_COLORS} = $saved_ls_colors; +} + +# If the string $S is a well-behaved file name, simply return it. +# If it contains white space, quotes, etc., quote it, and return the new string. +sub shell_quote($) +{ + my ($s) = @_; + if ($s =~ m![^\w+/.,-]!) + { + # Convert each single quote to '\'' + $s =~ s/\'/\'\\\'\'/g; + # Then single quote the string. + $s = "'$s'"; + } + return $s; +} + +# Set up files used by the setuid-etc tests; skip this entire test if +# that cannot be done. +sub setuid_setup() +{ + my $test = 'env test'; + system (qq(touch setuid && chmod u+s setuid && $test -u setuid && + touch setgid && chmod g+s setgid && $test -g setgid && + mkdir sticky && chmod +t sticky && $test -k sticky && + mkdir owt && chmod +t,o+w owt && $test -k owt && + mkdir owr && chmod o+w owr)) == 0 + or CuSkip::skip "$ME: cannot create setuid/setgid/sticky files," + . "so can't run this test\n"; +} + +sub mk_file(@) +{ + foreach my $f (@_) + { + open (F, '>', $f) && close F + or die "creating $f: $!\n"; + } +} + +sub mkdir_d {mkdir 'd',0755 or die "d: $!\n"} +sub rmdir_d {rmdir 'd' or die "d: $!\n"} +my $mkdir = {PRE => sub {mkdir_d}}; +my $rmdir = {POST => sub {rmdir_d}}; +my $mkdir_reg = {PRE => sub {mkdir_d; mk_file 'd/f' }}; +my $rmdir_reg = {POST => sub {unlink 'd/f' or die "d/f: $!\n"; + rmdir 'd' or die "d: $!\n"}}; + +my $mkdir2 = {PRE => sub {mkdir 'd',0755 or die "d: $!\n"; + mkdir 'd/e',0755 or die "d/e: $!\n" }}; +my $rmdir2 = {POST => sub {rmdir 'd/e' or die "d/e: $!\n"; + rmdir 'd' or die "d: $!\n" }}; + +my $target = {PRE => sub { + mkdir 'd',0755 or die "d: $!\n"; + symlink '.', 'd/X' or die "d/X: $!\n"; + push_ls_colors('ln=target') + }}; +my $target2 = {POST => sub {unlink 'd/X' or die "d/X: $!\n"; + rmdir 'd' or die "d: $!\n"; + restore_ls_colors + }}; +my $slink_d = {PRE => sub {symlink '/', 'd' or die "d: $!\n"; + push_ls_colors('ln=01;36:di=01;34:or=40;31;01') + }}; +my $unlink_d = {POST => sub {unlink 'd' or die "d: $!\n"; restore_ls_colors}}; + +my $mkdir_d_slink = {PRE => sub {mkdir 'd',0755 or die "d: $!\n"; + symlink '/', 'd/s' or die "d/s: $!\n" }}; +my $rmdir_d_slink = {POST => sub {unlink 'd/s' or die "d/s: $!\n"; + rmdir 'd' or die "d: $!\n" }}; + +sub make_j_d () +{ + mkdir 'j', 0700 or die "creating j: $!\n"; + mk_file 'j/d'; + chmod 0555, 'j/d' or die "making j/d executable: $!\n"; +} + +my @v_files = ( + '.0', '.9', + '.A', '.Z', '.a', '.z', '.zz~', '.zz', '.zz.~1~', '.zz.0', + '0', '9', + 'A', 'Z', 'a', 'z', 'zz~', 'zz', 'zz.~1~', 'zz.0'); +my $exe_in_subdir = {PRE => sub { make_j_d (); push_ls_colors('ex=01;32') }}; +my $remove_j = {POST => sub {unlink 'j/d' or die "j/d: $!\n"; + rmdir 'j' or die "j: $!\n"; + restore_ls_colors }}; + +my $e = "\e[0m"; +my $q_bell = {IN => {"q\a" => ''}}; +my @Tests = + ( + # test-name options input expected-output + # + # quoting tests............................................ + ['q-', $q_bell, {OUT => "q\a\n"}, {EXIT => 0}], + ['q-N', '-N', $q_bell, {OUT => "q\a\n"}, {ERR => ''}], + ['q-q', '-q', $q_bell, {OUT => "q?\n"}], + ['q-Q', '-Q', $q_bell, {OUT => "\"q\\a\"\n"}], + + ['q-qs-lit', '--quoting=literal', $q_bell, {OUT => "q\a\n"}], + ['q-qs-sh', '--quoting=shell', $q_bell, {OUT => "q\a\n"}], + ['q-qs-sh-a', '--quoting=shell-always',$q_bell, {OUT => "'q\a'\n"}], + ['q-qs-sh-e', '--quoting=shell-escape',$q_bell, {OUT => "'q'\$'\\a'\n"}], + ['q-qs-c', '--quoting=c', $q_bell, {OUT => "\"q\\a\"\n"}], + ['q-qs-esc', '--quoting=escape', $q_bell, {OUT => "q\\a\n"}], + ['q-qs-loc', '--quoting=locale', $q_bell, {OUT => "'q\\a'\n"}], + ['q-qs-cloc', '--quoting=clocale', $q_bell, {OUT => "\"q\\a\"\n"}], + + ['q-qs-lit-q', '--quoting=literal -q', $q_bell, {OUT => "q?\n"}], + ['q-qs-sh-q', '--quoting=shell -q', $q_bell, {OUT => "q?\n"}], + ['q-qs-sh-a-q', '--quoting=shell-al -q', $q_bell, {OUT => "'q?'\n"}], + ['q-qs-sh-e-q', '--quoting=shell-escape -q', + $q_bell, {OUT => "'q'\$'\\a'\n"}], + ['q-qs-c-q', '--quoting=c -q', $q_bell, {OUT => "\"q\\a\"\n"}], + ['q-qs-esc-q', '--quoting=escape -q', $q_bell, {OUT => "q\\a\n"}], + ['q-qs-loc-q', '--quoting=locale -q', $q_bell, {OUT => "'q\\a'\n"}], + ['q-qs-cloc-q', '--quoting=clocale -q', $q_bell, {OUT => "\"q\\a\"\n"}], + + ['q-qs-c-1', '--quoting=c', + {IN => {"t\004" => ''}}, {OUT => "\"t\\004\"\n"}], + + ['emptydir', 'd', {OUT => ''}, $mkdir, $rmdir], + ['emptydir-x2', 'd d', {OUT => "d:\n\nd:\n"}, $mkdir, $rmdir], + ['emptydir-R', '-R d', {OUT => "d:\n"}, $mkdir, $rmdir], + + # test 'ls -R .' ............................................ + ['R-dot', '--ignore="[a-ce-zA-Z]*" -R .', {OUT => ".:\nd\n\n\./d:\n"}, + $mkdir, $rmdir], + + ['slink-dir-F', '-F d', {OUT => "d@\n"}, $slink_d, $unlink_d], + ['slink-dir-dF', '-dF d', {OUT => "d@\n"}, $slink_d, $unlink_d], + ['slinkdir-dFH', '-dFH d', {OUT => "d/\n"}, $slink_d, $unlink_d], + ['slinkdir-dFL', '-dFL d', {OUT => "d/\n"}, $slink_d, $unlink_d], + + # Test for a bug that was fixed in coreutils-4.5.4. + ['sl-F-color', '-F --color=always d', + {OUT => "$e\e[01;36md$e\@\n"}, + $slink_d, $unlink_d], + ['sl-dF-color', '-dF --color=always d', + {OUT => "$e\e[01;36md$e\@\n"}, + $slink_d, $unlink_d], + + # A listing with no output should have no color sequences at all. + ['no-c-empty', '--color=always d', {OUT => ""}, $mkdir, $rmdir], + # A listing with only regular files should have no color sequences at all. + ['no-c-reg', '--color=always d', {OUT => "f\n"}, $mkdir_reg, $rmdir_reg], + + # Test for a bug fixed after coreutils-6.9. + ['sl-target', '--color=always d', + {OUT => "$e\e[01;34mX$e\n"}, $target, $target2], + + # Test for another bug fixed after coreutils-6.9. + # This one bites only for a system/file system with d_type support. + ['sl-dangle', '--color=always d', + {OUT => "$e\e[40;31;01mX$e\n"}, + {PRE => sub { + mkdir 'd',0755 or die "d: $!\n"; + symlink 'non-existent', 'd/X' or die "d/X: $!\n"; + push_ls_colors('or=40;31;01') + }}, + {POST => sub {unlink 'd/X' or die "d/X: $!\n"; + rmdir 'd' or die "d: $!\n"; + restore_ls_colors; }}, + ], + + # Test for a bug fixed after coreutils-8.2. + ['sl-dangle2', '-o --time-style=+:TIME: --color=always l', + {OUT_SUBST => 's/.*:TIME: //'}, + {OUT => "l -> nowhere\n"}, + {PRE => sub {symlink 'nowhere', 'l' or die "l: $!\n"; + push_ls_colors('ln=target') + }}, + {POST => sub {unlink 'l' or die "l: $!\n"; + restore_ls_colors; }}, + ], + ['sl-dangle3', '-o --time-style=+:TIME: --color=always l', + {OUT_SUBST => 's/.*:TIME: //'}, + {OUT => "$e\e[40ml$e -> \e[34mnowhere$e\n"}, + {PRE => sub {symlink 'nowhere', 'l' or die "l: $!\n"; + push_ls_colors('ln=target:or=40:mi=34:') + }}, + {POST => sub {unlink 'l' or die "l: $!\n"; + restore_ls_colors; }}, + ], + ['sl-dangle4', '-o --time-style=+:TIME: --color=always l', + {OUT_SUBST => 's/.*:TIME: //'}, + {OUT => "$e\e[36ml$e -> \e[35mnowhere$e\n"}, + {PRE => sub {symlink 'nowhere', 'l' or die "l: $!\n"; + push_ls_colors('ln=34:mi=35:or=36:') + }}, + {POST => sub {unlink 'l' or die "l: $!\n"; + restore_ls_colors; }}, + ], + ['sl-dangle5', '-o --time-style=+:TIME: --color=always l', + {OUT_SUBST => 's/.*:TIME: //'}, + {OUT => "$e\e[34ml$e -> \e[35mnowhere$e\n"}, + {PRE => sub {symlink 'nowhere', 'l' or die "l: $!\n"; + push_ls_colors('ln=34:mi=35:') + }}, + {POST => sub {unlink 'l' or die "l: $!\n"; + restore_ls_colors; }}, + ], + + # Test for a bug fixed after coreutils-8.13 + # where 'argetm' was erroneously printed for dangling links + # when ln=target was used in LS_COLORS + ['sl-dangle6', '-L --color=always d', + {OUT => "s\n"}, + {PRE => sub {mkdir 'd',0755 or die "d: $!\n"; + symlink 'dangle', 'd/s' or die "d/s: $!\n"; + push_ls_colors('ln=target') + }}, + {POST => sub {unlink 'd/s' or die "d/s: $!\n"; + rmdir 'd' or die "d: $!\n"; + restore_ls_colors; }}, + {ERR => "ls: cannot access 'd/s': No such file or directory\n"}, + {EXIT => 1} + ], + # Related to the above fix, is this case where + # the code simulates "linkok". In this case "linkmode" + # should always be zero, and hence not trigger any + # issues with type being set to C_LINK + ['sl-dangle7', '--color=always d', + {OUT => "$e\e[ms$e\n"}, + {PRE => sub {mkdir 'd',0755 or die "d: $!\n"; + symlink 'dangle', 'd/s' or die "d/s: $!\n"; + push_ls_colors('ln=target:or=:ex=:') + }}, + {POST => sub {unlink 'd/s' or die "d/s: $!\n"; + rmdir 'd' or die "d: $!\n"; + restore_ls_colors; }}, + ], + # Another case with simulated "linkok", that does + # actually use the value of 'ln' from $LS_COLORS. + # This path is not taken though when 'ln=target'. + ['sl-dangle8', '--color=always s', + {OUT => "$e\e[1;36ms$e\n"}, + {PRE => sub {symlink 'dangle', 's' or die "s: $!\n"; + push_ls_colors('ln=1;36:or=:') + }}, + {POST => sub {unlink 's' or die "s: $!\n"; + restore_ls_colors; }}, + ], + # The patch associated with sl-dangle[678] introduced a regression + # that was fixed after coreutils-8.19. This edge case triggers when + # listing a dir containing dangling symlinks, but with orphans uncolored. + # I.e., the same as the previous test, but listing the directory + # rather than the symlink directly. + ['sl-dangle9', '--color=always d', + {OUT => "$e\e[1;36ms$e\n"}, + {PRE => sub {mkdir 'd',0755 or die "d: $!\n"; + symlink 'dangle', 'd/s' or die "d/s: $!\n"; + push_ls_colors('ln=1;36:or=:') + }}, + {POST => sub {unlink 'd/s' or die "d/s: $!\n"; + rmdir 'd' or die "d: $!\n"; + restore_ls_colors; }}, + ], + + # Test for a bug that was introduced in coreutils-4.5.4; fixed in 4.5.5. + # To demonstrate it, the file in question (with executable bit set) + # must not be a command line argument. + ['color-exe1', '--color=always j', + {OUT => "$e\e[01;32md$e\n"}, + $exe_in_subdir, $remove_j], + + # From Stéphane Chazelas. + ['no-a-isdir-b', 'no-dir d', + {OUT => "d:\n"}, + {ERR => "ls: cannot access 'no-dir': No such file or directory\n"}, + $mkdir, $rmdir, {EXIT => 2}], + + ['recursive-2', '-R d', {OUT => "d:\ne\n\nd/e:\n"}, $mkdir2, $rmdir2], + + ['setuid-etc', '-1 -d --color=always owr owt setgid setuid sticky', + {OUT => + "$e\e[34;42mowr$e\n" + . "\e[30;42mowt$e\n" + . "\e[30;43msetgid$e\n" + . "\e[37;41msetuid$e\n" + . "\e[37;44msticky$e\n" + }, + + {PRE => sub { + push_ls_colors('ow=34;42:tw=30;42:sg=30;43:su=37;41:st=37;44'); }}, + {POST => sub { + unlink qw(setuid setgid); + foreach my $dir (qw(owr owt sticky)) {rmdir $dir} + restore_ls_colors; }}, + ], + + # For 5.97 and earlier, --file-type acted like --indicator-style=slash. + ['file-type', '--file-type d', {OUT => "s@\n"}, + $mkdir_d_slink, $rmdir_d_slink], + + # 7.1 had a regression in how -v -a ordered some files + ['version-sort', '-v -A ' . join (' ', @v_files), + {OUT => join ("\n", @v_files) . "\n"}, + {PRE => sub { mk_file @v_files }}, + {POST => sub { unlink @v_files }}, + ], + + # Test for the ls -1U bug fixed in coreutils-7.5. + # It is triggered only with -1U and with two or more arguments, + # at least one of which is a nonempty directory. + ['multi-arg-U1', '-U1 d no-such', + {OUT => "d:\nf\n"}, + {ERR_SUBST=>"s/ch':.*/ch':/"}, + {ERR => "$prog: cannot access 'no-such':\n"}, + $mkdir_reg, + $rmdir_reg, + {EXIT => 2}, + ], + ); + +umask 022; + +# Start with an unset LS_COLORS environment variable. +delete $ENV{LS_COLORS}; + +my $save_temps = $ENV{SAVE_TEMPS}; +my $verbose = $ENV{VERBOSE}; + +setuid_setup; +my $fail = run_tests ($ME, $prog, \@Tests, $save_temps, $verbose); +$fail + and exit 1; + +# Be careful to use the just-build dircolors. +my $env = qx/dircolors -b/; +$env =~ s/^LS_COLORS=\'//; +$env =~ s/\';.*//sm; +$ENV{LS_COLORS} = $env; + +setuid_setup; +$fail = run_tests ($ME, $prog, \@Tests, $save_temps, $verbose); +exit $fail; diff --git a/tests/ls/ls-time.sh b/tests/ls/ls-time.sh new file mode 100755 index 0000000..5585d62 --- /dev/null +++ b/tests/ls/ls-time.sh @@ -0,0 +1,145 @@ +#!/bin/sh +# Test some of ls's sorting options. + +# Copyright (C) 1998-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# Avoid any possible glitches due to daylight-saving changes near the +# timestamps used during the test. +TZ=UTC0 +export TZ + +t1='1998-01-15 21:00' +t2='1998-01-15 22:00' +t3='1998-01-15 23:00' + +u1='1998-01-14 11:00' +u2='1998-01-14 12:00' +u3='1998-01-14 13:00' + +touch -m -d "$t3" a || framework_failure_ +touch -m -d "$t2" b || framework_failure_ +touch -m -d "$t1" c || framework_failure_ + +touch -a -d "$u3" c || framework_failure_ +touch -a -d "$u2" b || framework_failure_ +# Make sure A has ctime at least 1 second more recent than C's. +sleep 2 +touch -a -d "$u1" a || framework_failure_ +# Updating the atime is usually enough to update the ctime, but on +# Solaris 10's tmpfs, ctime is not updated, so force an update here: +{ ln a a-ctime && rm a-ctime; } || framework_failure_ + + +# A has ctime more recent than C. +set $(ls -c a c) +test "$*" = 'a c' || fail=1 + +# Sleep so long in an attempt to avoid spurious failures +# due to NFS caching and/or clock skew. +sleep 2 + +# Create a link, updating c's ctime. +ln c d || framework_failure_ + +# Before we go any further, verify that touch's -m option works. +set -- $(ls --full -l --time=mtime a) +case "$*" in + *" $t3:00.000000000 +0000 a") ;; + *) + # This might be what's making HPUX 11 systems fail this test. + cat >&2 << EOF +A basic test of touch -m has just failed, so the subsequent +tests in this file will not be run. + +In the output below, the date of last modification for 'a' should +have been $t3. +EOF + ls --full -l a + skip_ "touch -m -d '$t3' didn't work" + ;; +esac + +# Ensure that touch's -a option works. +set -- $(ls --full -lu a) +case "$*" in + *" $u1:00.000000000 +0000 a") ;; + *) + # This might be what's making HPUX 11 systems fail this test. + cat >&2 << EOF +A fundamental touch -a test has just failed, so the subsequent +tests in this file will not be run. + +In the output below, the date of last access for 'a' should +have been $u1. +EOF + ls --full -lu a + Exit 77 + ;; +esac + +set $(ls -ut a b c) +test "$*" = 'c b a' && : || fail=1 +test $fail = 1 && ls -l --full-time --time=access a b c + +set $(ls -t a b c) +test "$*" = 'a b c' && : || fail=1 +test $fail = 1 && ls -l --full-time a b c + +# Now, C should have ctime more recent than A. +set $(ls -ct a c) +if test "$*" = 'c a'; then + : ok +else + # In spite of documentation, (e.g., stat(2)), neither link nor chmod + # update a file's st_ctime on SunOS4.1.4. + cat >&2 << \EOF +failed ls ctime test -- this failure is expected at least for SunOS4.1.4 +and for tmpfs file systems on Solaris 5.5.1. +It is also expected to fail on a btrfs file system until +https://bugzilla.redhat.com/591068 is addressed. + +In the output below, 'c' should have had a ctime more recent than +that of 'a', but does not. +EOF + #' + ls -ctl --full-time a c + fail=1 +fi + +# This check is ineffective if: +# en_US locale is not on the system. +# The system en_US message catalog has a specific TIME_FMT translation, +# which was inadvertently the case between coreutils 8.1 and 8.5 inclusive. + +if gettext --version >/dev/null 2>&1; then + + default_tf1='%b %e %Y' + en_tf1=$(LC_ALL=en_US gettext coreutils "$default_tf1") + + if test "$default_tf1" = "$en_tf1"; then + LC_ALL=en_US ls -l c >en_output + ls -l --time-style=long-iso c >liso_output + if compare en_output liso_output; then + fail=1 + echo "Long ISO TIME_FMT being used for en_US locale." >&2 + fi + fi +fi + +Exit $fail diff --git a/tests/ls/m-option.sh b/tests/ls/m-option.sh new file mode 100755 index 0000000..3b8cdcd --- /dev/null +++ b/tests/ls/m-option.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# exercise the -m option + +# Copyright (C) 2003-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +seq 2000 > b || framework_failure_ +touch a || framework_failure_ + + +# Before coreutils-5.1.1, the following would output a space after the comma. +ls -w2 -m a b > out || fail=1 + +# Before coreutils-5.1.1, the following would produce leading white space. +# All of the sed business is because the sizes are not portable. +ls -sm a b | sed 's/^[0-9]/0/;s/, [0-9][0-9]* b/, 12 b/' >> out || fail=1 +cat <<\EOF > exp || framework_failure_ +a, +b +0 a, 12 b +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/multihardlink.sh b/tests/ls/multihardlink.sh new file mode 100755 index 0000000..0d35981 --- /dev/null +++ b/tests/ls/multihardlink.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# Ensure "ls --color" properly colors names of hard linked files. + +# Copyright (C) 2008-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +working_umask_or_skip_ + +touch file file1 || framework_failure_ +ln file1 file2 || skip_ "can't create hard link" +code_mh='44;37' +code_ex='01;32' +code_png='01;35' +c0=$(printf '\033[0m') +c_mh=$(printf '\033[%sm' $code_mh) +c_ex=$(printf '\033[%sm' $code_ex) +c_png=$(printf '\033[%sm' $code_png) + +# regular file - not hard linked +LS_COLORS="mh=$code_mh" ls -U1 --color=always file > out || fail=1 +printf "file\n" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# hard links +LS_COLORS="mh=$code_mh" ls -U1 --color=always file1 file2 > out || fail=1 +printf "$c0${c_mh}file1$c0 +${c_mh}file2$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# hard links and png (hard link coloring takes precedence) +mv file2 file2.png || framework_failure_ +LS_COLORS="mh=$code_mh:*.png=$code_png" ls -U1 --color=always file1 file2.png \ + > out || fail=1 +printf "$c0${c_mh}file1$c0 +${c_mh}file2.png$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# hard links and exe (exe coloring takes precedence) +chmod a+x file2.png || framework_failure_ +LS_COLORS="mh=$code_mh:*.png=$code_png:ex=$code_ex" \ + ls -U1 --color=always file1 file2.png > out || fail=1 +chmod a-x file2.png || framework_failure_ +printf "$c0${c_ex}file1$c0 +${c_ex}file2.png$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# hard links and png (hard link coloring disabled => png coloring enabled) +LS_COLORS="mh=00:*.png=$code_png" ls -U1 --color=always file1 file2.png > out \ + || fail=1 +printf "file1 +$c0${c_png}file2.png$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +# hard links and png (hard link coloring not enabled explicitly => png coloring) +LS_COLORS="*.png=$code_png" ls -U1 --color=always file1 file2.png > out \ + || fail=1 +printf "file1 +$c0${c_png}file2.png$c0 +" > out_ok || framework_failure_ +compare out out_ok || fail=1 + +Exit $fail diff --git a/tests/ls/nameless-uid.sh b/tests/ls/nameless-uid.sh new file mode 100755 index 0000000..94cdf40 --- /dev/null +++ b/tests/ls/nameless-uid.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Ensure that ls -l works on files with nameless uid and/or gid + +# Copyright (C) 2006-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +require_root_ +require_perl_ + +nameless_uid=$($PERL -e ' + foreach my $i (1000..16*1024) { getpwuid $i or (print "$i\n"), exit } +') + +if test x$nameless_uid = x; then + skip_ "couldn't find a nameless UID" +fi + +touch f || framework_failure_ +chown $nameless_uid f || framework_failure_ + + +set -- $(ls -o f) || fail=1 +test $3 = $nameless_uid || fail=1 + +Exit $fail diff --git a/tests/ls/no-arg.sh b/tests/ls/no-arg.sh new file mode 100755 index 0000000..bb72d83 --- /dev/null +++ b/tests/ls/no-arg.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# make sure ls and 'ls -R' do the right thing when invoked with no arguments. + +# Copyright (C) 2001-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir -p dir/subdir || framework_failure_ +touch dir/subdir/file2 || framework_failure_ +ln -s f symlink || framework_failure_ + +cat > exp <<\EOF || framework_failure_ +dir +exp +out +symlink +EOF + + +ls -1 > out || fail=1 + +compare exp out || fail=1 + +cat > exp <<\EOF +.: +dir +exp +out +symlink + +./dir: +subdir + +./dir/subdir: +file2 +EOF + +ls -R1 > out || fail=1 + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/no-cap.sh b/tests/ls/no-cap.sh new file mode 100755 index 0000000..bee7bee --- /dev/null +++ b/tests/ls/no-cap.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# ensure that an empty "ca=" attribute disables ls's capability-checking + +# Copyright (C) 2008-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +require_strace_ capget + +LS_COLORS=ca=1; export LS_COLORS +strace -e capget ls --color=always > /dev/null 2> out || fail=1 +$EGREP 'capget\(' out || skip_ "your ls doesn't call capget" + +rm -f out + +LS_COLORS=ca=:; export LS_COLORS +strace -e capget ls --color=always > /dev/null 2> out || fail=1 +$EGREP 'capget\(' out && fail=1 + +Exit $fail diff --git a/tests/ls/quote-align.sh b/tests/ls/quote-align.sh new file mode 100755 index 0000000..54a6fd0 --- /dev/null +++ b/tests/ls/quote-align.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# test quote alignment combinations + +# Copyright (C) 2016-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +dirname='dir:name' +mkdir "$dirname" || framework_failure_ +touch "$dirname/a b" "$dirname/c.foo" || framework_failure_ + +e=$(printf '\033') +color_code='0;31;42' +c_pre="$e[0m$e[${color_code}m" +c_post="$e[0m" + +cat <<EOF >exp || framework_failure_ +'$dirname': +'a b' ${c_pre}c.foo${c_post} +'$dirname': +'a b' ${c_pre}c.foo${c_post} +'$dirname': +'a b' + ${c_pre}c.foo${c_post} +'$dirname': +'a b' +${c_pre}c.foo${c_post} +'$dirname': +'a b', ${c_pre}c.foo${c_post} +'$dirname': +'a b' ${c_pre}c.foo${c_post} + +EOF + +for opt in '-w0 -x' '-x' '-og' '-1' '-m' '-C'; do + env TERM=xterm LS_COLORS="*.foo=$color_code" TIME_STYLE=+T \ + ls $opt -R --quoting=shell-escape --color=always "$dirname" >> out || fail=1 +done + +# Append a newline, to accommodate less-capable versions of sed. +echo >> out || framework_failure_ + +# Strip possible varying portion of long format +sed -e 's/.*T //' -e '/^total/d' out > k && mv k out + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/readdir-mountpoint-inode.sh b/tests/ls/readdir-mountpoint-inode.sh new file mode 100755 index 0000000..18c5d53 --- /dev/null +++ b/tests/ls/readdir-mountpoint-inode.sh @@ -0,0 +1,73 @@ +#!/bin/sh +# ensure that ls -i works also for mount points + +# Copyright (C) 2009-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# We use --local here so as to not activate +# potentially very many remote mounts. +df --local --out=target | sed -n '/^\/./p' > mount_points +test -s mount_points || + skip_ "this test requires a non-root mount point" + +# Given e.g., /dev/shm, produce the list of GNU ls options that +# let us list just that entry using readdir data from its parent: +# ls -i -I '[^s]*' -I 's[^h]*' -I 'sh[^m]*' -I 'shm?*' -I '.?*' \ +# -I '?' -I '??' /dev + +ls_ignore_options() +{ + name=$1 + opts="-I '.?*' -I '$name?*'" + while :; do + glob=$(echo "$name"|sed 's/\(.*\)\(.\)$/\1[^\2]*/') + opts="$opts -I '$glob'" + name=$(echo "$name"|sed 's/.$//') + test -z "$name" && break + glob=$(echo "$name"|sed 's/./?/g') + opts="$opts -I '$glob'" + done + echo "$opts" +} + +inode_via_readdir() +{ + mount_point=$1 + base=$(basename "$mount_point") + case "$base" in + .*) skip_ 'mount point component starts with "."' ;; + *[*?]*) skip_ 'mount point component contains "?" or "*"' ;; + esac + opts=$(ls_ignore_options "$base") + parent_dir=$(dirname "$mount_point") + ls_out=$(eval "ls -i $opts '$parent_dir'") + test $? -eq 0 || \ + skip_ "'$parent_dir' is not readable for current user" + echo $ls_out | sed 's/ .*//' +} + +while read dir; do + readdir_inode=$(inode_via_readdir "$dir") + test $? = 77 && continue + stat_inode=$(timeout 1 stat --format=%i "$dir") + # If stat fails or says the inode is 0, skip $dir. + case $stat_inode in 0|'') continue;; esac + test "$readdir_inode" = "$stat_inode" || fail=1 +done < mount_points + +Exit $fail diff --git a/tests/ls/recursive.sh b/tests/ls/recursive.sh new file mode 100755 index 0000000..16554a8 --- /dev/null +++ b/tests/ls/recursive.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# 4.1.1 and 4.1.2 had a bug whereby some recursive listings +# didn't include a blank line between per-directory groups of files. + +# Copyright (C) 2001-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir x y a b c a/1 a/2 a/3 || framework_failure_ +touch f a/1/I a/1/II || framework_failure_ + + +# This first example is from Andreas Schwab's bug report. +ls -R1 a b c > out || fail=1 +cat <<EOF > exp +a: +1 +2 +3 + +a/1: +I +II + +a/2: + +a/3: + +b: + +c: +EOF + +compare exp out || fail=1 + +rm -rf out exp +ls -R1 x y f > out || fail=1 +cat <<EOF > exp +f + +x: + +y: +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/removed-directory.sh b/tests/ls/removed-directory.sh new file mode 100755 index 0000000..692d05d --- /dev/null +++ b/tests/ls/removed-directory.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# If ls is asked to list a removed directory (e.g., the parent process's +# current working directory has been removed by another process), it +# should not emit an error message merely because the directory is removed. + +# Copyright (C) 2020-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +cwd=$(pwd) +mkdir d || framework_failure_ +cd d || framework_failure_ +rmdir ../d || skip_ "can't remove working directory on this platform" + +# On NFS, 'ls' would run into the error "Stale file handle". +test -d . || skip_ "can't examine removed working directory on this platform" + +ls >"$cwd"/out 2>"$cwd"/err || fail=1 +cd "$cwd" || framework_failure_ + +compare /dev/null out || fail=1 +compare /dev/null err || fail=1 + +Exit $fail diff --git a/tests/ls/root-rel-symlink-color.sh b/tests/ls/root-rel-symlink-color.sh new file mode 100755 index 0000000..d8663e4 --- /dev/null +++ b/tests/ls/root-rel-symlink-color.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# Exercise the 8.17 ls bug with coloring relative-named symlinks in "/". + +# Copyright (C) 2012-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls test + +symlink_to_rel= +for i in /*; do + # Skip non-symlinks: + env test -h "$i" || continue + + # Skip dangling symlinks: + env test -e "$i" || continue + + # Skip any symlink-to-absolute-name: + case $(readlink "$i") in /*) continue ;; esac + + symlink_to_rel=$i + break +done + +test -z "$symlink_to_rel" \ + && skip_ no relative symlink in / + +e='\33' +color_code='01;36' +c_pre="$e[0m$e[${color_code}m" +c_post="$e[0m" +printf "$c_pre$symlink_to_rel$c_post\n" > exp || framework_failure_ + +env TERM=xterm LS_COLORS="ln=$color_code:or=1;31;42" \ + ls -d --color=always "$symlink_to_rel" > out || fail=1 + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/rt-1.sh b/tests/ls/rt-1.sh new file mode 100755 index 0000000..4a8b948 --- /dev/null +++ b/tests/ls/rt-1.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# Make sure name is used as secondary key when sorting on mtime or ctime. + +# Copyright (C) 1998-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls touch + +date=1998-01-15 + +touch -d "$date" c || framework_failure_ +touch -d "$date" a || framework_failure_ +touch -d "$date" b || framework_failure_ + + +ls -1t a b c > out || fail=1 +cat <<EOF > exp +a +b +c +EOF +compare exp out || fail=1 + +rm -rf out exp +ls -1rt a b c > out || fail=1 +cat <<EOF > exp +c +b +a +EOF +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/selinux-segfault.sh b/tests/ls/selinux-segfault.sh new file mode 100755 index 0000000..4e0d551 --- /dev/null +++ b/tests/ls/selinux-segfault.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# Ensure we don't segfault in selinux handling + +# Copyright (C) 2008-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# ls -l /proc/sys would segfault when built against libselinux1 2.0.15-2+b1 +f=/proc/sys +test -r $f || f=. +ls -l $f > out || fail=1 + +# ls <= 8.32 would segfault when printing +# the security context of broken symlink targets +mkdir sedir || framework_failure_ +ln -sf missing sedir/broken || framework_failure_ +returns_ 1 ls -L -R -Z -m sedir > out || fail=1 + +Exit $fail diff --git a/tests/ls/slink-acl.sh b/tests/ls/slink-acl.sh new file mode 100755 index 0000000..ab9fb8f --- /dev/null +++ b/tests/ls/slink-acl.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# verify that ls -lL works when applied to a symlink to an ACL'd file + +# Copyright (C) 2011-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +require_setfacl_ + +touch k || framework_failure_ +setfacl -m user::r-- k || framework_failure_ +ln -s k s || framework_failure_ + +set _ $(ls -Log s); shift; link=$1 +set _ $(ls -og k); shift; reg=$1 + +test "$link" = "$reg" || fail=1 + +Exit $fail diff --git a/tests/ls/sort-width-option.sh b/tests/ls/sort-width-option.sh new file mode 100755 index 0000000..bffd2e9 --- /dev/null +++ b/tests/ls/sort-width-option.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Exercise the --sort=width option. + +# Copyright (C) 2021-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir subdir || framework_failure_ +touch subdir/aaaaa || framework_failure_ +touch subdir/bbb || framework_failure_ +touch subdir/cccc || framework_failure_ +touch subdir/d || framework_failure_ +touch subdir/zz || framework_failure_ + + +ls --sort=width subdir > out || fail=1 +cat <<\EOF > exp || framework_failure_ +d +zz +bbb +cccc +aaaaa +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/stat-dtype.sh b/tests/ls/stat-dtype.sh new file mode 100755 index 0000000..794fcef --- /dev/null +++ b/tests/ls/stat-dtype.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# Ensure that ls --file-type does not call stat unnecessarily. +# Also check for the dtype-related (and fs-type dependent) bug +# in coreutils-6.0 that made ls -CF columns misaligned. + +# Copyright (C) 2006-2023 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 <https://www.gnu.org/licenses/>. + +# The trick is to create an un-stat'able symlink and to see if ls +# can report its type nonetheless, using dirent.d_type. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +# Skip this test unless "." is on a file system with useful d_type info. +# FIXME: This uses "ls -p" to decide whether to test "ls" with other options, +# but if ls's d_type code is buggy then "ls -p" might be buggy too. +mkdir -p c/d || framework_failure_ +chmod a-x c || framework_failure_ +if test "X$(ls -p c 2>&1)" != Xd/; then + skip_ "'.' is not on a suitable file system for this test" +fi + +mkdir d || framework_failure_ +ln -s / d/s || framework_failure_ +chmod 600 d || framework_failure_ + +mkdir -p e/a2345 e/b || framework_failure_ +chmod 600 e || framework_failure_ + + +ls --file-type d > out || fail=1 +cat <<\EOF > exp || framework_failure_ +s@ +EOF + +compare exp out || fail=1 + +# Check for the ls -CF misaligned-columns bug: +ls -CF e > out || fail=1 + +# coreutils-6.0 would print two spaces after the first slash, +# rather than the appropriate TAB. +printf 'a2345/\tb/\n' > exp || framework_failure_ + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/stat-failed.sh b/tests/ls/stat-failed.sh new file mode 100755 index 0000000..642ac4a --- /dev/null +++ b/tests/ls/stat-failed.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# Verify that ls works properly when it fails to stat a file that is +# not mentioned on the command line. + +# Copyright (C) 2006-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +skip_if_root_ + +LS_MINOR_PROBLEM=1 + +mkdir d || framework_failure_ +ln -s / d/s || framework_failure_ +chmod 600 d || framework_failure_ + + +returns_ 1 ls -Log d > out || fail=1 + +# Linux 2.6.32 client with Isilon OneFS always returns d_type==DT_DIR ('d') +# Newer Linux 3.10.0 returns the more correct DT_UNKNOWN ('?') +grep '^[l?]?' out || skip_ 'unrecognized d_type returned' + +cat <<\EOF > exp || framework_failure_ +total 0 +?????????? ? ? ? s +EOF + +sed 's/^l/?/' out | compare exp - || fail=1 + +# Ensure that the offsets in --dired output are accurate. +rm -f out exp +returns_ $LS_MINOR_PROBLEM ls --dired -l d > out || fail=1 + +cat <<\EOF > exp || framework_failure_ + total 0 + ?????????? ? ? ? ? ? s +//DIRED// 44 45 +//DIRED-OPTIONS// --quoting-style=literal +EOF + +sed 's/^ l/ ?/' out | compare exp - || fail=1 + +Exit $fail diff --git a/tests/ls/stat-free-color.sh b/tests/ls/stat-free-color.sh new file mode 100755 index 0000000..b02c06b --- /dev/null +++ b/tests/ls/stat-free-color.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# Show that --color need not use stat, as long as we have d_type support. + +# Copyright (C) 2011-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +require_strace_ stat +require_dirent_d_type_ + +stats='stat' +# List of other _file name_ stat functions to increase coverage. +other_stats='statx lstat stat64 lstat64 newfstatat fstatat64' +for stat in $other_stats; do + strace -qe "$stat" true > /dev/null 2>&1 && + stats="$stats,$stat" +done + +# Disable enough features via LS_COLORS so that ls --color +# can do its job without calling stat (other than the obligatory +# one-call-per-command-line argument). +cat <<EOF > color-without-stat || framework_failure_ +RESET 0 +DIR 01;34 +LINK 01;36 +FIFO 40;33 +SOCK 01;35 +DOOR 01;35 +BLK 40;33;01 +CHR 40;33;01 +ORPHAN 00 +SETUID 00 +SETGID 00 +CAPABILITY 00 +STICKY_OTHER_WRITABLE 00 +OTHER_WRITABLE 00 +STICKY 00 +EXEC 00 +MULTIHARDLINK 00 +EOF +eval $(dircolors -b color-without-stat) + +# The system may perform additional stat-like calls before main. +# Furthermore, underlying library functions may also implicitly +# add an extra stat call, e.g. opendir since glibc-2.21-360-g46f894d. +# Finally, ls(1) makes a stat call for stdout, but only in the case +# when there is something to output. +# To get the comparison right, first get a baseline count for running +# 'ls -a' with one empty directory argument. Then, compare that with +# the invocation under test. +mkdir d || framework_failure_ + +count_stats() { grep -vE '\+\+\+|ENOSYS|NOTSUP' "$1" | wc -l; } +strace -q -o log1 -e $stats ls -a --color=always d || fail=1 +n_stat1=$(count_stats log1) || framework_failure_ + +test $n_stat1 = 0 \ + && skip_ 'No stat calls recognized on this platform' + +# Populate the test directory. +mkdir d/subdir \ + && touch d/regf \ + && ln d/regf d/hlink \ + && ln -s regf d/slink \ + && ln -s nowhere d/dangle \ + || framework_failure_ + +# Invocation under test. +strace -q -o log2 -e $stats ls --color=always d || fail=1 +n_stat2=$(count_stats log2) || framework_failure_ + +# Expect the same number of stat calls. +test $n_stat1 = $n_stat2 \ + || { fail=1; head -n30 log*; } + +Exit $fail diff --git a/tests/ls/stat-free-symlinks.sh b/tests/ls/stat-free-symlinks.sh new file mode 100755 index 0000000..27f3414 --- /dev/null +++ b/tests/ls/stat-free-symlinks.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# ensure that ls does not stat a symlink in an unusual case + +# Copyright (C) 2007-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +require_strace_ stat + +stats='stat' +# List of other _file name_ stat functions to increase coverage. +other_stats='statx lstat stat64 lstat64 newfstatat fstatat64' +for stat in $other_stats; do + strace -qe "$stat" true > /dev/null 2>&1 && + stats="$stats,$stat" +done + +# The system may perform additional stat-like calls before main. +# Furthermore, underlying library functions may also implicitly +# add an extra stat call, e.g. opendir since glibc-2.21-360-g46f894d. +# To avoid counting those, first get a baseline count for running +# ls with one empty directory argument. Then, compare that with the +# invocation under test. +count_stats() { grep -vE '\+\+\+|ENOSYS|NOTSUP' "$1" | wc -l; } +mkdir d || framework_failure_ +strace -q -o log1 -e $stats ls -F --color=always d || fail=1 +n_stat1=$(count_stats log1) || framework_failure_ + +test $n_stat1 = 0 \ + && skip_ 'No stat calls recognized on this platform' + + +touch x || framework_failure_ +chmod a+x x || framework_failure_ +ln -s x link-to-x || framework_failure_ + + +# ls from coreutils 6.9 would unnecessarily stat a symlink in an unusual case: +# When not coloring orphan and missing entries, and without ln=target, +# ensure that ls -F (or -d, or -l: i.e., when not dereferencing) +# does not stat a symlink to directory, and does still color that +# symlink and an executable file properly. + +LS_COLORS='or=0:mi=0:ex=01;32:ln=01;35' \ + strace -qe $stats -o log2 ls -F --color=always x link-to-x > out.tmp || fail=1 +n_stat2=$(count_stats log2) || framework_failure_ + +# Expect one more stat call, +# which failed with coreutils 6.9 and earlier, which had 2. +test $n_stat1 = $(($n_stat2 - 1)) \ + || { fail=1; head -n30 log*; } + +# Check that output is colored, as requested, too. +{ + printf '\033[0m\033[01;35mlink-to-x\033[0m@\n' + printf '\033[01;32mx\033[0m*\n' +} > exp || fail=1 +# Elide info messages strace can send to stdout of the form: +# [ Process PID=1234 runs in 32 bit mode. ] +sed '/Process PID=/d' out.tmp > out +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/stat-vs-dirent.sh b/tests/ls/stat-vs-dirent.sh new file mode 100755 index 0000000..b29889c --- /dev/null +++ b/tests/ls/stat-vs-dirent.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# Ensure that d_ino (from ls -di) and st_ino (from stat --format=%i) match. + +# Copyright (C) 2006-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + + +root_dev_ino=$(stat --format=%d-%i /) +t=$(pwd) +while :; do + if ls -i1 "$t" > tmp; 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") || + skip_ "error stating: $t/$file" # removed or newlines in name etc. + + # 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 + + fail=1 + break + fi + fi + + t=$(cd "$t/.."; pwd) + dev_ino=$(stat --format=%d-%i "$t") + test $dev_ino = $root_dev_ino && break +done + +Exit $fail diff --git a/tests/ls/symlink-loop.sh b/tests/ls/symlink-loop.sh new file mode 100755 index 0000000..0e0b0bf --- /dev/null +++ b/tests/ls/symlink-loop.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# Exercise ls symlink ELOOP handling + +# Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +ln -s loop loop || framework_failure_ +cat loop >/dev/null 2>&1 && skip_ 'symlink loops not detected' + +# With coreutils <= 9.3 we would dereference symlinks on the command line +# and thus fail to display a symlink that could not be traversed. +ls loop || fail=1 +ls -l loop || fail=1 +ls -l --color=always loop || fail=1 + +# Ensure these still fail +returns_ 2 ls -H loop || fail=1 +returns_ 2 ls -L loop || fail=1 + +Exit $fail diff --git a/tests/ls/symlink-quote.sh b/tests/ls/symlink-quote.sh new file mode 100755 index 0000000..ba45de5 --- /dev/null +++ b/tests/ls/symlink-quote.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# Ensure symlinks are quoted appropriately + +# Copyright (C) 2017-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +ln -s 'needs quoting' symlink || framework_failure_ + +ls -l --quoting-style='shell-escape' symlink >out || fail=1 + +# Coreutils v8.26 and 8.27 failed to quote the target name +grep "symlink -> 'needs quoting'\$" out >/dev/null || + { cat out; fail=1; } + +Exit $fail diff --git a/tests/ls/symlink-slash.sh b/tests/ls/symlink-slash.sh new file mode 100755 index 0000000..f62e44d --- /dev/null +++ b/tests/ls/symlink-slash.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# Do dereference a symlink arg if its name is written with a trailing slash. + +# Copyright (C) 1999-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir dir || framework_failure_ +ln -s dir symlink || framework_failure_ + +set $(ls -l symlink/) + +# Prior to fileutils-4.0k, the following would have output '... symlink -> dir'. +test "$*" = 'total 0' && : || fail=1 + +Exit $fail diff --git a/tests/ls/time-style-diag.sh b/tests/ls/time-style-diag.sh new file mode 100755 index 0000000..af53ba3 --- /dev/null +++ b/tests/ls/time-style-diag.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# Ensure that an invalid --time-style=ARG is diagnosed the way we want. + +# Copyright (C) 2011-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +returns_ 2 ls -l --time-style=XX > out 2> err || fail=1 + +cat <<\EOF > exp || framework_failure_ +ls: invalid argument 'XX' for 'time style' +Valid arguments are: + - [posix-]full-iso + - [posix-]long-iso + - [posix-]iso + - [posix-]locale + - +FORMAT (e.g., +%H:%M) for a 'date'-style format +Try 'ls --help' for more information. +EOF + +compare exp err || fail=1 +compare /dev/null out || fail=1 + +Exit $fail diff --git a/tests/ls/w-option.sh b/tests/ls/w-option.sh new file mode 100755 index 0000000..555e98c --- /dev/null +++ b/tests/ls/w-option.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# exercise the -w option + +# Copyright (C) 2015-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls +getlimits_ + +touch a b || framework_failure_ +chmod a+x a || framework_failure_ + +# Negative values disallowed +returns_ 2 ls -w-1 || fail=1 + +# Verify octal parsing (especially since 0 is allowed) +returns_ 2 ls -w08 || fail=1 + +# Overflowed values are capped at SIZE_MAX +ls -w$SIZE_OFLOW || fail=1 + +# After coreutils 8.24 -w0 means no limit +# and delimiting with spaces +ls -w0 -x -T1 a b > out || fail=1 +printf '%s\n' 'a b' > exp || framework_failure_ +compare exp out || fail=1 + +# Ensure that 0 line length doesn't cause division by zero +TERM=xterm ls -w0 -x --color=always || fail=1 + +# coreutils <= 8.24 could display 1 column too few +ls -w4 -x -T0 a b > out || fail=1 +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/x-option.sh b/tests/ls/x-option.sh new file mode 100755 index 0000000..30c2e7c --- /dev/null +++ b/tests/ls/x-option.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Exercise the -x option. + +# Copyright (C) 2007-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir subdir || framework_failure_ +touch subdir/b || framework_failure_ +touch subdir/a || framework_failure_ + + +# Coreutils 6.8 and 6.9 would output this in the wrong order. +ls -x subdir > out || fail=1 +ls -rx subdir >> out || fail=1 +cat <<\EOF > exp || framework_failure_ +a b +b a +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/ls/zero-option.sh b/tests/ls/zero-option.sh new file mode 100755 index 0000000..d3c9f0d --- /dev/null +++ b/tests/ls/zero-option.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Verify behavior of ls --zero. + +# Copyright 2021-2023 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ ls + +mkdir dir && touch dir/a dir/b dir/cc || framework_failure_ + +allowed_options='-l' # explicit -l with --zero is allowed +LC_ALL=C ls $allowed_options --zero dir >out || fail=1 +grep '^total' out || fail=1 # Ensure -l honored + +disallowed_options='-l --dired' # dired only enabled with -l +returns_ 2 ls $disallowed_options --zero dir || fail=1 + +disabled_options='--color=always -x -m -C -Q -q' +LC_ALL=C ls $disabled_options --zero dir >out || fail=1 +tr '\n' '\0' <<EOF >exp +a +b +cc +EOF + +compare exp out || fail=1 + +Exit $fail |