Skip to content

Commit

Permalink
(perl #127663) work around what appears to be a freebsd bug
Browse files Browse the repository at this point in the history
renameat() on FreeBSD 11 fails if the paths supplied are absolute
paths.
  • Loading branch information
tonycoz committed Sep 18, 2017
1 parent ac1ba09 commit 84dbe61
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
28 changes: 26 additions & 2 deletions doio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,30 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
return NULL;
}

#ifdef ARGV_USE_ATFUNCTIONS
# if defined(__FreeBSD__)

/* FreeBSD 11 renameat() mis-behaves strangely with absolute paths in cases where the
* equivalent rename() succeeds
*/
static int
S_my_renameat(int olddfd, const char *oldpath, int newdfd, const char *newpath) {
/* this is intended only for use in Perl_do_close() */
assert(olddfd == newdfd);
assert(PERL_FILE_IS_ABSOLUTE(oldpath) == PERL_FILE_IS_ABSOLUTE(newpath));
if (PERL_FILE_IS_ABSOLUTE(oldpath)) {
return PerlLIO_rename(oldpath, newpath);
}
else {
return renameat(olddfd, oldpath, newdfd, newpath);
}
}

# else
# define S_my_renameat(dh1, pv1, dh2, pv2) renameat((dh1), (pv1), (dh2), (pv2))
# endif /* if defined(__FreeBSD__) */
#endif

/* explicit renamed to avoid C++ conflict -- kja */
bool
Perl_do_close(pTHX_ GV *gv, bool not_implicit)
Expand Down Expand Up @@ -1320,7 +1344,7 @@ Perl_do_close(pTHX_ GV *gv, bool not_implicit)
#ifdef HAS_RENAME
if (
# ifdef ARGV_USE_ATFUNCTIONS
renameat(dfd, orig_pv, dfd, SvPVX(*back_psv)) < 0
S_my_renameat(dfd, orig_pv, dfd, SvPVX(*back_psv)) < 0
# else
PerlLIO_rename(orig_pv, SvPVX(*back_psv)) < 0
# endif
Expand Down Expand Up @@ -1360,7 +1384,7 @@ Perl_do_close(pTHX_ GV *gv, bool not_implicit)
if (
#ifdef HAS_RENAME
# ifdef ARGV_USE_ATFUNCTIONS
renameat(dfd, SvPVX(*temp_psv), dfd, orig_pv) < 0
S_my_renameat(dfd, SvPVX(*temp_psv), dfd, orig_pv) < 0
# else
PerlLIO_rename(SvPVX(*temp_psv), orig_pv) < 0
# endif
Expand Down
15 changes: 14 additions & 1 deletion t/run/switches.t
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ BEGIN {

BEGIN { require "./test.pl"; require "./loc_tools.pl"; }

plan(tests => 136);
plan(tests => 137);

use Config;

Expand Down Expand Up @@ -552,6 +552,19 @@ CODE
rmdir "$work.bak" or die "Cannot remove mask backup directory: $!";
}

{
# test with absolute paths, this was failing on FreeBSD 11ish due
# to a bug in renameat()
my $abs_work = File::Spec->rel2abs($work);
fresh_perl_is(<<'CODE', "",
while (<>) {
print;
}
CODE
{ stderr => 1, args => [ $abs_work ], switches => [ "-i" ] },
"abs paths");
}

# we now use temp files for in-place editing, make sure we didn't leave
# any behind in the above test
opendir my $d, "inplacetmp" or die "Cannot opendir inplacetmp: $!";
Expand Down

0 comments on commit 84dbe61

Please sign in to comment.