Skip to content

Commit

Permalink
[io grant] Fix race in &indir(IO::Path …)
Browse files Browse the repository at this point in the history
Do not use IO::Path.chdir… at least for now… as it is racy. Instead,
copy over the file tests into &indir impl.

Fixes race for IO::Path argument, but not for Str, which probably
can't be fixed, since the race is inside teh coercer when Str gets
coerced into an IO::Path.
  • Loading branch information
zoffixznet committed Apr 2, 2017
1 parent a0ef2ed commit ca1acb7
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions src/core/io_operators.pm
Expand Up @@ -162,14 +162,46 @@ multi sub spurt(Cool $path, $contents, |c) {
}

sub chdir(|c) { $*CWD .= chdir(|c) }
sub indir(IO() $path, &what, |c) {

proto sub indir(|) {*}
multi sub indir(IO() $path, &what, :$test!) {
DEPRECATED(
:what<:$test argument>,
'individual named parameters (e.g. :r, :w, :x)',
"v2017.03.101.ga.5800.a.1", "v6.d", :up(*),
);
indir $path, &what, |$test.words.map(* => True).Hash;
}
multi sub indir(IO() $path, &what, :$d = True, :$r, :$w, :$x) {
{ # NOTE: we need this extra block so that the IO() coercer doesn't
# use our (empty at the time) $*CWD when making the IO::Path object

# We call .chdir for the sake of its doing the :d:r:w:x tests
nqp::if(
nqp::istype((my $*CWD = $path.chdir($path,|c)), Failure),
$*CWD, what,
nqp::stmts(
nqp::unless(
nqp::unless(nqp::isfalse($d), $path.d),
fail X::IO::Chdir.new: :$path, :os-error(
nqp::if($path.e, 'is not a directory', 'does not exist')
)
),
nqp::unless(
nqp::unless(nqp::isfalse($r), $path.r),
fail X::IO::Chdir.new: :$path,
:os-error("did not pass :r test")
),
nqp::unless(
nqp::unless(nqp::isfalse($w), $path.w),
fail X::IO::Chdir.new: :$path,
:os-error("did not pass :w test")
),
nqp::unless(
nqp::unless(nqp::isfalse($x), $path.x),
fail X::IO::Chdir.new: :$path,
:os-error("did not pass :x test")
),
my $*CWD = $path,
),
what
)
}
}
Expand Down

0 comments on commit ca1acb7

Please sign in to comment.