blob: bf51ac27888e4c7a930613326371cfd65ec24516 (
plain)
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
|