From bf574deec8e811db230566fb085028aa6958d0fd Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Wed, 7 Jun 2023 13:42:36 +0100 Subject: [PATCH] ls: display command line symlinks that return ELOOP * src/ls.c (gobble_file): Ensure we lstat() a symlink specified on the command line, if we receive ELOOP from stat(). * tests/ls/symlink-loop.sh: Add a new test. * tests/local.mk: Reference the new test. * NEWS: Mention the bug fix. Fixes https://bugs.gnu.org/63931 --- NEWS | 4 ++++ src/ls.c | 2 +- tests/local.mk | 1 + tests/ls/symlink-loop.sh | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100755 tests/ls/symlink-loop.sh diff --git a/NEWS b/NEWS index 97f180ed1d..e47701962a 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,10 @@ GNU coreutils NEWS -*- outline -*- Previously such file names would have caused the strip process to fail. [This bug was present in "the beginning".] + ls now shows symlinks specified on the command line that can't be traversed. + Previously a "Too many levels of symbolic links" diagnostic was given. + [This bug was present in "the beginning".] + 'pr --length=1 --double-space' no longer enters an infinite loop. [This bug was present in "the beginning".] diff --git a/src/ls.c b/src/ls.c index fbeb9b6dcf..33f692bb41 100644 --- a/src/ls.c +++ b/src/ls.c @@ -3480,7 +3480,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, break; need_lstat = (err < 0 - ? errno == ENOENT + ? (errno == ENOENT || errno == ELOOP) : ! S_ISDIR (f->stat.st_mode)); if (!need_lstat) break; diff --git a/tests/local.mk b/tests/local.mk index fb5c9c4a5a..23a518a227 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -643,6 +643,7 @@ all_tests = \ tests/ls/stat-free-color.sh \ tests/ls/stat-free-symlinks.sh \ tests/ls/stat-vs-dirent.sh \ + tests/ls/symlink-loop.sh \ tests/ls/symlink-quote.sh \ tests/ls/symlink-slash.sh \ tests/ls/time-style-diag.sh \ diff --git a/tests/ls/symlink-loop.sh b/tests/ls/symlink-loop.sh new file mode 100755 index 0000000000..0e0b0bf473 --- /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 . + +. "${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 -- 2.47.2