1#!/bin/sh
2# Use du to exercise a corner of fts's FTS_LOGICAL code.
3# Show that du fails with ELOOP (Too many levels of symbolic links)
4# when it encounters that condition.
5
6# Copyright (C) 2006-2023 Free Software Foundation, Inc.
7
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17
18# You should have received a copy of the GNU General Public License
19# along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
21. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
22print_ver_ du
23
24# Create lots of directories, each containing a single symlink
25# pointing at the next directory in the list.
26
27# This number should be larger than the number of symlinks allowed in
28# file name resolution, but not too large as a number of entries
29# in a single directory.
30n=400
31
32dir_list=$(seq $n)
33mkdir $dir_list || framework_failure_
34file=1
35i_minus_1=0
36for i in $dir_list $(expr $n + 1); do
37  case $i_minus_1 in
38  0) ;;
39  *)
40    ln -s ../$i $i_minus_1/s || framework_failure_
41    file=$file/s;;
42  esac
43  i_minus_1=$i
44done
45echo foo > $i || framework_failure_
46
47# If a system can handle this many symlinks in a file name,
48# just skip this test.
49
50# The following also serves to record in 'err' the string
51# corresponding to strerror (ELOOP).  This is necessary because while
52# Linux/libc gives 'Too many levels of symbolic links', Solaris
53# renders it as "Number of symbolic links encountered during path
54# name traversal exceeds MAXSYMLINKS".
55
56cat $file > /dev/null 2> err &&
57    skip_ 'Your system appears to be able to handle more than $n symlinks
58in file name resolution'
59too_many=$(sed 's/.*: //' err)
60
61
62# With coreutils-5.93 there was no failure.
63# With coreutils-5.94 we get the desired diagnostic:
64# du: cannot access '1/s/s/s/.../s': Too many levels of symbolic links
65du -L 1 > /dev/null 2> out1 && fail=1
66sed "s, .1/s/s/s/[/s]*',," out1 > out || framework_failure_
67
68echo "du: cannot access: $too_many" > exp || framework_failure_
69
70compare exp out || fail=1
71
72Exit $fail
73