Skip to content

Commit 84dbe61

Browse files
committed
(perl #127663) work around what appears to be a freebsd bug
renameat() on FreeBSD 11 fails if the paths supplied are absolute paths.
1 parent ac1ba09 commit 84dbe61

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

doio.c

+26-2
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,30 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
11911191
return NULL;
11921192
}
11931193

1194+
#ifdef ARGV_USE_ATFUNCTIONS
1195+
# if defined(__FreeBSD__)
1196+
1197+
/* FreeBSD 11 renameat() mis-behaves strangely with absolute paths in cases where the
1198+
* equivalent rename() succeeds
1199+
*/
1200+
static int
1201+
S_my_renameat(int olddfd, const char *oldpath, int newdfd, const char *newpath) {
1202+
/* this is intended only for use in Perl_do_close() */
1203+
assert(olddfd == newdfd);
1204+
assert(PERL_FILE_IS_ABSOLUTE(oldpath) == PERL_FILE_IS_ABSOLUTE(newpath));
1205+
if (PERL_FILE_IS_ABSOLUTE(oldpath)) {
1206+
return PerlLIO_rename(oldpath, newpath);
1207+
}
1208+
else {
1209+
return renameat(olddfd, oldpath, newdfd, newpath);
1210+
}
1211+
}
1212+
1213+
# else
1214+
# define S_my_renameat(dh1, pv1, dh2, pv2) renameat((dh1), (pv1), (dh2), (pv2))
1215+
# endif /* if defined(__FreeBSD__) */
1216+
#endif
1217+
11941218
/* explicit renamed to avoid C++ conflict -- kja */
11951219
bool
11961220
Perl_do_close(pTHX_ GV *gv, bool not_implicit)
@@ -1320,7 +1344,7 @@ Perl_do_close(pTHX_ GV *gv, bool not_implicit)
13201344
#ifdef HAS_RENAME
13211345
if (
13221346
# ifdef ARGV_USE_ATFUNCTIONS
1323-
renameat(dfd, orig_pv, dfd, SvPVX(*back_psv)) < 0
1347+
S_my_renameat(dfd, orig_pv, dfd, SvPVX(*back_psv)) < 0
13241348
# else
13251349
PerlLIO_rename(orig_pv, SvPVX(*back_psv)) < 0
13261350
# endif
@@ -1360,7 +1384,7 @@ Perl_do_close(pTHX_ GV *gv, bool not_implicit)
13601384
if (
13611385
#ifdef HAS_RENAME
13621386
# ifdef ARGV_USE_ATFUNCTIONS
1363-
renameat(dfd, SvPVX(*temp_psv), dfd, orig_pv) < 0
1387+
S_my_renameat(dfd, SvPVX(*temp_psv), dfd, orig_pv) < 0
13641388
# else
13651389
PerlLIO_rename(SvPVX(*temp_psv), orig_pv) < 0
13661390
# endif

t/run/switches.t

+14-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ BEGIN {
1212

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

15-
plan(tests => 136);
15+
plan(tests => 137);
1616

1717
use Config;
1818

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

555+
{
556+
# test with absolute paths, this was failing on FreeBSD 11ish due
557+
# to a bug in renameat()
558+
my $abs_work = File::Spec->rel2abs($work);
559+
fresh_perl_is(<<'CODE', "",
560+
while (<>) {
561+
print;
562+
}
563+
CODE
564+
{ stderr => 1, args => [ $abs_work ], switches => [ "-i" ] },
565+
"abs paths");
566+
}
567+
555568
# we now use temp files for in-place editing, make sure we didn't leave
556569
# any behind in the above test
557570
opendir my $d, "inplacetmp" or die "Cannot opendir inplacetmp: $!";

0 commit comments

Comments
 (0)