Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: v1_1dev
Fetching contributors…

Cannot retrieve contributors at this time

file 91 lines (81 sloc) 1.92 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
#
# $Id$
#
# The class for temporary files.
# o creates a temporary file, which name is "basename.pid.n" with mode "w+".
# o Tempfile objects can be used like IO object.
# o with tmpfile.close(true) created temporary files are removed.
# o created files are also removed on script termination.
# o with Tempfile#open, you can reopen the temporary file.
# o file mode of the temporary files are 0600.

require 'delegate'
require 'final'

class Tempfile < SimpleDelegator
  Max_try = 10

  def Tempfile.callback(path)
    lambda{
      print "removing ", path, "..." if $DEBUG
      if File.exist?(path)
File.unlink(path)
      end
      if File.exist?(path + '.lock')
Dir.rmdir(path + '.lock')
      end
      print "done\n" if $DEBUG
    }
  end

  def initialize(basename, tmpdir = '/tmp')
    umask = File.umask(0177)
    tmpname = lock = nil
    begin
      n = 0
      while true
begin
tmpname = sprintf('%s/%s.%d.%d', tmpdir, basename, $$, n)
lock = tmpname + '.lock'
unless File.exist?(lock)
Dir.mkdir(lock)
break
end
rescue
raise "cannot generate tmpfile `%s'" % tmpname if n >= Max_try
#sleep(1)
end
n += 1
      end

      @clean_files = Tempfile.callback(tmpname)
      ObjectSpace.define_finalizer(self, @clean_files)

      @tmpfile = File.open(tmpname, 'w+')
      @tmpname = tmpname
      super(@tmpfile)
      Dir.rmdir(lock)
    ensure
      File.umask(umask)
    end
  end

  def Tempfile.open(*args)
    Tempfile.new(*args)
  end

  def open
    @tmpfile.close if @tmpfile
    @tmpfile = File.open(@tmpname, 'r+')
    __setobj__(@tmpfile)
  end

  def close(real=false)
    @tmpfile.close if @tmpfile
    @tmpfile = nil
    if real
      @clean_files.call
      ObjectSpace.undefine_finalizer(self)
    end
  end
end

if __FILE__ == $0
# $DEBUG = true
  f = Tempfile.new("foo")
  f.print("foo\n")
  f.close
  f.open
  p f.gets # => "foo\n"
  f.close(true)
end
Something went wrong with that request. Please try again.