Project

General

Profile

Feature #7148 ยป patch.diff

Glass_saga (Masaki Matsushita), 10/12/2012 02:04 PM

View differences:

lib/tempfile.rb
# $Id$
#
require 'delegate'
require 'tmpdir'
require 'thread'
......
# Tempfile itself however may not be entirely thread-safe. If you access the
# same Tempfile object from multiple threads then you should protect it with a
# mutex.
class Tempfile < DelegateClass(File)
class Tempfile < File
include Dir::Tmpname
@@tmpmap = {}
# call-seq:
# new(basename, [tmpdir = Dir.tmpdir], [options])
#
......
else
opts = perm
end
@data[1] = @tmpfile = File.open(tmpname, mode, opts)
@data[1] = @tmpfile = super(tmpname, mode, opts)
@data[0] = @tmpname = tmpname
@mode = mode & ~(File::CREAT|File::EXCL)
perm or opts.freeze
@opts = opts
end
@@tmpmap[@tmpname] = 1
@data[2] = @@tmpmap
end
super(@tmpfile)
def dup
@@tmpmap[@tmpname] += 1
super
end
# Opens or reopens the file with mode "r+".
def open
@tmpfile.close if @tmpfile
@tmpfile = File.open(@tmpname, @mode, @opts)
@data[1] = @tmpfile
__setobj__(@tmpfile)
end
def _close # :nodoc:
begin
@tmpfile.close if @tmpfile
ensure
@tmpfile = nil
@data[1] = nil if @data
end
opts = @opts.is_a?(Hash) ? @opts : nil
@tmpfile = reopen(@tmpname, @mode, opts)
end
protected :_close
# Closes the file. If +unlink_now+ is true, then the file will be unlinked
# (deleted) after closing. Of course, you can choose to later call #unlink
......
# If you don't explicitly unlink the temporary file, the removal
# will be delayed until the object is finalized.
def close(unlink_now=false)
begin
super() if @tmpfile
ensure
@tmpfile = nil
@data[1] = nil if @data
end
if unlink_now
close!
else
_close
unlink
ObjectSpace.undefine_finalizer(self)
end
nil
end
# Closes and unlinks (deletes) the file. Has the same effect as called
# <tt>close(true)</tt>.
def close!
_close
unlink
ObjectSpace.undefine_finalizer(self)
close(true)
end
# Unlinks (deletes) the file from the filesystem. One should always unlink
......
def call(*args)
return if @pid != $$
path, tmpfile = *@data
path, tmpfile, tmpmap = *@data
STDERR.print "removing ", path, "..." if $DEBUG
tmpfile.close if tmpfile
if path
if path && tmpmap.has_key?(path) && (tmpmap[path] -= 1) == 0
begin
File.unlink(path)
rescue Errno::ENOENT
......
end
STDERR.print "done\n" if $DEBUG
ensure
tmpmap.delete(path)
end
end
# :startdoc:
test/test_tempfile.rb
assert_equal(0600, t.stat.mode & 0777)
end
end
end
def test_dup
t = tempfile("foo")
t_dup = t.dup
assert(t_dup.is_a?(File))
end
def test_duped_finalizer
t = Tempfile.new("foo")
path = t.path
t_dup = t.dup
t = nil
GC.start
assert(File.exist?(path))
end
end
    (1-1/1)