summaryrefslogtreecommitdiff
path: root/lib/tempfile.rb
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-08-13 05:45:20 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-08-13 05:45:20 +0000
commit65a5162550f58047974793cdc8067a970b2435c0 (patch)
tree082bb7d5568f3b2e36e3fe166e9f3039394fcf44 /lib/tempfile.rb
parentfcd020c83028f5610d382e85a2df00223e12bd7e (diff)
1.4.0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@520 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/tempfile.rb')
-rw-r--r--lib/tempfile.rb94
1 files changed, 94 insertions, 0 deletions
diff --git a/lib/tempfile.rb b/lib/tempfile.rb
new file mode 100644
index 0000000..11a8fba
--- /dev/null
+++ b/lib/tempfile.rb
@@ -0,0 +1,94 @@
+#
+# $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=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp')
+ umask = File.umask(0177)
+ begin
+ n = 0
+ while true
+ begin
+ tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
+ lock = tmpname + '.lock'
+ unless File.exist?(tmpname) or 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
+
+ def path
+ @tmpname
+ 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