* lib/tempfile.rb: refactoring.

* use warn instead of STDERR.print
  * remove @tmpname and use @tmpfile.path
  * introduce @unlinked flag
  * Remover takes only @tmpfile
  * mode will be modified just before file reopen

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50682 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
glass 2015-05-30 01:29:48 +00:00
Родитель e214058956
Коммит 354c9747e4
2 изменённых файлов: 38 добавлений и 55 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Sat May 30 10:26:09 2015 Masaki Matsushita <glass.saga@gmail.com>
* lib/tempfile.rb: refactoring.
* use warn instead of STDERR.print
* remove @tmpname and use @tmpfile.path
* introduce @unlinked flag
* Remover takes only @tmpfile
* mode will be modified just before file reopen
Sat May 30 09:02:51 2015 Eric Wong <e@80x24.org>
* include/ruby/intern.h (rb_generic_ivar_table): deprecate

Просмотреть файл

@ -123,41 +123,29 @@ class Tempfile < DelegateClass(File)
# If Tempfile.new cannot find a unique filename within a limited
# number of tries, then it will raise an exception.
def initialize(basename="", tmpdir=nil, mode: 0, **options)
if block_given?
warn "Tempfile.new doesn't call the given block."
end
@data = []
@clean_proc = Remover.new(@data)
ObjectSpace.define_finalizer(self, @clean_proc)
warn "Tempfile.new doesn't call the given block." if block_given?
@mode = mode|File::RDWR|File::CREAT|File::EXCL
::Dir::Tmpname.create(basename, tmpdir, options) do |tmpname, n, opts|
mode |= File::RDWR|File::CREAT|File::EXCL
opts[:perm] = 0600
@data[1] = @tmpfile = File.open(tmpname, mode, opts)
@data[0] = @tmpname = tmpname
@mode = mode & ~(File::CREAT|File::EXCL)
opts.freeze
@opts = opts
@tmpfile = File.open(tmpname, @mode, opts)
@opts = opts.freeze
end
ObjectSpace.define_finalizer(self, Remover.new(@tmpfile))
super(@tmpfile)
end
# Opens or reopens the file with mode "r+".
def open
@tmpfile.close if @tmpfile
@tmpfile = File.open(@tmpname, @mode, @opts)
@data[1] = @tmpfile
_close
mode = @mode & ~(File::CREAT|File::EXCL)
@tmpfile = File.open(@tmpfile.path, mode, @opts)
__setobj__(@tmpfile)
end
def _close # :nodoc:
begin
@tmpfile.close if @tmpfile
ensure
@tmpfile = nil
@data[1] = nil if @data
end
@tmpfile.close unless @tmpfile.closed?
end
protected :_close
@ -168,18 +156,14 @@ class Tempfile < DelegateClass(File)
# If you don't explicitly unlink the temporary file, the removal
# will be delayed until the object is finalized.
def close(unlink_now=false)
if unlink_now
close!
else
_close
end
_close
unlink if unlink_now
end
# Closes and unlinks (deletes) the file. Has the same effect as called
# <tt>close(true)</tt>.
def close!
_close
unlink
close(true)
end
# Unlinks (deletes) the file from the filesystem. One should always unlink
@ -216,37 +200,32 @@ class Tempfile < DelegateClass(File)
# # to do so again.
# end
def unlink
return unless @tmpname
return if @unlinked
begin
File.unlink(@tmpname)
File.unlink(@tmpfile.path)
rescue Errno::ENOENT
rescue Errno::EACCES
# may not be able to unlink on Windows; just ignore
return
end
# remove tmpname from remover
@data[0] = @data[1] = nil
@tmpname = nil
ObjectSpace.undefine_finalizer(self)
@unlinked = true
end
alias delete unlink
# Returns the full path name of the temporary file.
# This will be nil if #unlink has been called.
def path
@tmpname
@unlinked ? nil : @tmpfile.path
end
# Returns the size of the temporary file. As a side effect, the IO
# buffer is flushed before determining the size.
def size
if @tmpfile
@tmpfile.flush
@tmpfile.stat.size
elsif @tmpname
File.size(@tmpname)
if !@tmpfile.closed?
@tmpfile.size # File#size calls rb_io_flush_raw()
else
0
File.size?(@tmpfile.path)
end
end
alias length size
@ -261,28 +240,23 @@ class Tempfile < DelegateClass(File)
end
class Remover
def initialize(data)
@pid = $$
@data = data
def initialize(tmpfile)
@pid = Process.pid
@tmpfile = tmpfile
end
def call(*args)
return if @pid != $$
return if @pid != Process.pid
path, tmpfile = @data
warn "removing #{@tmpfile.path}..." if $DEBUG
STDERR.print "removing ", path, "..." if $DEBUG
tmpfile.close if tmpfile
if path
begin
File.unlink(path)
rescue Errno::ENOENT
end
@tmpfile.close if @tmpfile.closed?
begin
File.unlink(@tmpfile.path)
rescue Errno::ENOENT
end
STDERR.print "done\n" if $DEBUG
warn "done" if $DEBUG
end
end