lib/tempfile.rb
DEFINITIONS
This source file includes following functions.
1 #
2 # $Id: tempfile.rb,v 1.10 2002/06/04 07:34:19 matz Exp $
3 #
4 # The class for temporary files.
5 # o creates a temporary file, which name is "basename.pid.n" with mode "w+".
6 # o Tempfile objects can be used like IO object.
7 # o with tempfile.close(true) created temporary files are removed.
8 # o created files are also removed on script termination.
9 # o with Tempfile#open, you can reopen the temporary file.
10 # o file mode of the temporary files are 0600.
11
12 require 'delegate'
13
14 class Tempfile < SimpleDelegator
15 Max_try = 10
16
17 def Tempfile.callback(path, data)
18 pid = $$
19 lambda{
20 if pid == $$
21 print "removing ", path, "..." if $DEBUG
22 data[0].close if data[0]
23 if File.exist?(path)
24 File.unlink(path)
25 end
26 if File.exist?(path + '.lock')
27 Dir.rmdir(path + '.lock')
28 end
29 print "done\n" if $DEBUG
30 end
31 }
32 end
33
34 def initialize(basename, tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp')
35 if $SAFE > 0 and tmpdir.tainted?
36 tmpdir = '/tmp'
37 end
38 n = 0
39 while true
40 begin
41 tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
42 lock = tmpname + '.lock'
43 unless File.exist?(tmpname) or File.exist?(lock)
44 Dir.mkdir(lock)
45 break
46 end
47 rescue
48 raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
49 #sleep(1)
50 end
51 n += 1
52 end
53
54 @protect = []
55 @clean_files = Tempfile.callback(tmpname, @protect)
56 ObjectSpace.define_finalizer(self, @clean_files)
57
58 @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
59 @protect[0] = @tmpfile
60 @tmpname = tmpname
61 super(@tmpfile)
62 Dir.rmdir(lock)
63 end
64
65 def Tempfile.open(*args)
66 Tempfile.new(*args)
67 end
68
69 def open
70 @tmpfile.close if @tmpfile
71 @tmpfile = File.open(@tmpname, 'r+')
72 @protect[0] = @tmpfile
73 __setobj__(@tmpfile)
74 end
75
76 def close(real=false)
77 @tmpfile.close if @tmpfile
78 @protect[0] = @tmpfile = nil
79 if real
80 @clean_files.call
81 ObjectSpace.undefine_finalizer(self)
82 end
83 end
84
85 def path
86 @tmpname
87 end
88
89 def size
90 if @tmpfile
91 @tmpfile.flush
92 @tmpfile.stat.size
93 else
94 0
95 end
96 end
97 end
98
99 if __FILE__ == $0
100 # $DEBUG = true
101 f = Tempfile.new("foo")
102 f.print("foo\n")
103 f.close
104 f.open
105 p f.gets # => "foo\n"
106 f.close(true)
107 end