J
Joel VanderWerf
In the ftools.rb implementation of File.makedirs (ruby 1.8.1-preview3),
there is apparently a race condition. It can result in an error like:
/usr/local/lib/ruby/1.8/ftools.rb:139:in `mkdir': File exists -
/tmp/fsdb-test/TestConcurrency14475//Results (Errno::EEXIST)
def makedirs(*dirs)
verbose = if dirs[-1].is_a? String then false else dirs.pop end
# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
mode = 0755
for dir in dirs
parent = dirname(dir)
next if parent == dir or FileTest.directory? dir
makedirs parent unless FileTest.directory? parent
$deferr.print "mkdir ", dir, "\n" if verbose
if basename(dir) != ""
Dir.mkdir dir, mode
end
end
end
This can be avoided by simply rescuing that exception around the
Dir.mkdir call:
def makedirs(*dirs)
verbose = if dirs[-1].is_a? String then false else dirs.pop end
# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
mode = 0755
for dir in dirs
parent = dirname(dir)
next if parent == dir or FileTest.directory? dir
makedirs parent unless FileTest.directory? parent
$deferr.print "mkdir ", dir, "\n" if verbose
if basename(dir) != ""
begin
Dir.mkdir dir, mode
rescue Errno::EEXIST
end
end
end
end
(Maybe in the verbose case this exception should be logged to $deferr.)
there is apparently a race condition. It can result in an error like:
/usr/local/lib/ruby/1.8/ftools.rb:139:in `mkdir': File exists -
/tmp/fsdb-test/TestConcurrency14475//Results (Errno::EEXIST)
def makedirs(*dirs)
verbose = if dirs[-1].is_a? String then false else dirs.pop end
# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
mode = 0755
for dir in dirs
parent = dirname(dir)
next if parent == dir or FileTest.directory? dir
makedirs parent unless FileTest.directory? parent
$deferr.print "mkdir ", dir, "\n" if verbose
if basename(dir) != ""
Dir.mkdir dir, mode
end
end
end
This can be avoided by simply rescuing that exception around the
Dir.mkdir call:
def makedirs(*dirs)
verbose = if dirs[-1].is_a? String then false else dirs.pop end
# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
mode = 0755
for dir in dirs
parent = dirname(dir)
next if parent == dir or FileTest.directory? dir
makedirs parent unless FileTest.directory? parent
$deferr.print "mkdir ", dir, "\n" if verbose
if basename(dir) != ""
begin
Dir.mkdir dir, mode
rescue Errno::EEXIST
end
end
end
end
(Maybe in the verbose case this exception should be logged to $deferr.)