3
# Ensure that pwd works even when run from a very deep directory.
5
# Copyright (C) 2006-2012 Free Software Foundation, Inc.
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
23
require_readable_root_
29
# Don't use CuTmpdir here, since File::Temp's use of rmtree can't
30
# remove the deep tree we create.
31
$PERL -Tw -I"$abs_srcdir/tests" -MCuSkip -- - <<\EOF
33
# Show that pwd works even when the length of the resulting
34
# directory name is longer than PATH_MAX.
37
(my $ME = $ENV{ARGV_0}) =~ s|.*/||;
39
sub normalize_to_cwd_relative ($$$)
41
my ($dir, $dev, $ino) = @_;
46
$slash = index $dir, '/', $slash + 1;
48
and die "$ME: $dir does not contain old CWD\n";
49
my $dir_prefix = $slash ? substr ($dir, 0, $slash) : '/';
50
my ($d, $i) = (stat $dir_prefix)[0, 1];
51
defined $d && defined $i
52
or die "$ME: $dir_prefix: stat failed: $!\n";
53
$d eq $dev && $i eq $ino
54
and return substr $dir, $slash + 1;
58
# Set up a safe, well-known environment
59
delete @ENV{qw(BASH_ENV CDPATH ENV)};
62
# Taint checking requires a sanitized $PATH. This script performs no $PATH
63
# search, so on most Unix-based systems, it is fine simply to clear $ENV{PATH}.
64
# However, on Cygwin, it's used to find cygwin1.dll, so set it.
65
$ENV{PATH} = '/bin:/usr/bin';
67
# Save CWD's device and inode numbers.
68
my ($dev, $ino) = (stat '.')[0, 1];
70
# Construct the expected "."-relative part of pwd's output.
73
my $expected = "/$z" x $n;
74
# Remove the leading "/".
75
substr ($expected, 0, 1) = '';
81
or CuSkip::skip "$ME: skipping this test; cannot create long "
82
. "directory name at depth $i: $!\n";
87
my $abs_top_builddir = $ENV{abs_top_builddir};
89
or die "$ME: envvar abs_top_builddir not defined\n";
90
my $build_src_dir = "$abs_top_builddir/src";
91
$build_src_dir =~ m!^([-+.:/\w]+)$!
92
or CuSkip::skip "$ME: skipping this test; odd build source directory name:\n"
96
my $pwd_binary = "$build_src_dir/pwd";
99
or die "$ME: $pwd_binary is not an executable file\n";
100
chomp (my $actual = qx!$pwd_binary!);
102
# Convert the absolute name from pwd into a $CWD-relative name.
103
# This is necessary in order to avoid a spurious failure when run
104
# from a directory in a bind-mounted partition. What happens is
105
# pwd reads a ".." that contains two or more entries with identical
106
# dev,ino that match the ones we're looking for, and it chooses a
107
# name that does not correspond to the one already recorded in $CWD.
108
$actual = normalize_to_cwd_relative $actual, $dev, $ino;
110
if ($expected ne $actual)
112
my $e_len = length $expected;
113
my $a_len = length $actual;
114
warn "expected len: $e_len\n";
115
warn "actual len: $a_len\n";
116
warn "expected: $expected\n";
117
warn "actual: $actual\n";