Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File::Find return symlink to follow_skip==2 #14444

Open
p5pRT opened this issue Jan 25, 2015 · 3 comments
Open

File::Find return symlink to follow_skip==2 #14444

p5pRT opened this issue Jan 25, 2015 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 25, 2015

Migrated from rt.perl.org#123672 (status was 'open')

Searchable as RT123672$

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2015

From qd1qupwe.hs2@20minutemail.com

# perldoc File​::Find

"follow"
Causes symbolic links to be followed.
...
There is a variable $File​::Find​::fullname which holds the
absolute pathname of the file with all symbolic links resolved.
...
"follow_skip==2" causes File​::Find to ignore any duplicate files and
directories but to proceed normally otherwise.

I got next result​:

# create files
$ mkdir -p a/b b; touch a/b/X; ln -s ../a/b/X b/

# test.pl
use File​::Find;
find( {
  wanted => sub{ /X$/o && print $File​::Find​::fullname,"\n"},
  follow => 1,
  follow_skip => 2
}, '.');

# result​:
$ perl test.pl
/tmp/test_box2/a/b/X
/tmp/test_box2/b/X # <-- got symlink in result

Is that wrong behavior for follow => 1 and follow_skip => 2 options ?

What's going on?

sub Follow_SymLink($) {
..
  while (-l _) { # <-- 1. true
...
  $NewName= PathCombine($AbsName, readlink($AbsName)); # <-- 2. $NewName keep true filename
...
  if ($full_check && defined $DEV && $SLnkSeen{$DEV, $INO}++) { # 3. <-- [!] TRUE for $SLnkSeen{$DEV, $INO}
  if ( ($follow_skip < 1) || ((-d _) && ($follow_skip < 2)) ) {
  die "$AbsName encountered a second time";
  }
  else {
  return undef; # <-- 4. our exit point
  }
  }
...
}

sub _find_dir_symlnk($$$) {
...
  # follow symbolic links / do an lstat
  $new_loc = Follow_SymLink($loc_pref.$FN); # <-- 1. we got undef for symlink

  # ignore if invalid symlink
  unless (defined $new_loc) {
  if (!defined -l _ && $dangling_symlinks) { # <-- 2. false
  ...
  }
  else {
  $fullname = $loc_pref . $FN; # <-- 3. so, full filename point to symlink, not content
  }
  $name = $dir_pref . $FN;
  $_ = ($no_chdir ? $name : $FN);
  { $wanted_callback->() }; # <-- 4. callback got symlink in result
  next;
  }
...
}

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2015

From @tonycoz

On Sun Jan 25 03​:57​:02 2015, qd1qupwe.hs2@​20minutemail.com wrote​:

# perldoc File​::Find

"follow"
Causes symbolic links to be followed.
...
There is a variable $File​::Find​::fullname which holds the
absolute pathname of the file with all symbolic links resolved.
...
"follow_skip==2" causes File​::Find to ignore any duplicate files and
directories but to proceed normally otherwise.

I got next result​:

# create files
$ mkdir -p a/b b; touch a/b/X; ln -s ../a/b/X b/

# test.pl
use File​::Find;
find( {
wanted => sub{ /X$/o && print $File​::Find​::fullname,"\n"},
follow => 1,
follow_skip => 2
}, '.');

# result​:
$ perl test.pl
/tmp/test_box2/a/b/X
/tmp/test_box2/b/X # <-- got symlink in result

Is that wrong behavior for follow => 1 and follow_skip => 2 options ?

What's going on?

sub Follow_SymLink($) {
..
while (-l _) { # <-- 1. true
...
$NewName= PathCombine($AbsName, readlink($AbsName)); # <-- 2.
$NewName keep true filename
...
if ($full_check && defined $DEV && $SLnkSeen{$DEV, $INO}++) { # 3.
<-- [!] TRUE for $SLnkSeen{$DEV, $INO}
if ( ($follow_skip < 1) || ((-d _) && ($follow_skip < 2)) ) {
die "$AbsName encountered a second time";
}
else {
return undef; # <-- 4. our exit point
}
}
...
}

sub _find_dir_symlnk($$$) {
...
# follow symbolic links / do an lstat
$new_loc = Follow_SymLink($loc_pref.$FN); # <-- 1. we got undef for
symlink

# ignore if invalid symlink
unless (defined $new_loc) {
if (!defined -l _ && $dangling_symlinks) { # <-- 2. false
...
}
else {
$fullname = $loc_pref . $FN; # <-- 3. so, full filename point to
symlink, not content
}
$name = $dir_pref . $FN;
$_ = ($no_chdir ? $name : $FN);
{ $wanted_callback->() }; # <-- 4. callback got symlink in result
next;
}
...
}

This appears to have changed in​:

commit 1da2e9e
Author​: Victor Efimov <victor@​vsespb.ru>
Date​: Tue Nov 19 01​:18​:26 2013 +0100

  Check symlink status before setting File​::Find​::fullname to undef.
 
  Problem reported by James Avera in RT #120388. Patches supplied by Victor
  Efimov, then adapted to new testing functions in ext/File-Find/t/find.t.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2015

The RT System itself - Status changed from 'new' to 'open'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants