summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-12-23 14:51:01 +0000
committerknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-12-23 14:51:01 +0000
commit3ebec77d8acc235be33e51b2c7a13b1ec7cf1a2b (patch)
treef8edd673aa7561f2163885cac767c6d2ee100e0d
parent33451f070ea4dc53e4c396219aca8ecd8bcb7799 (diff)
downloadruby-3ebec77d8acc235be33e51b2c7a13b1ec7cf1a2b.tar.gz
Merge from 1.7:
* lib/tempfile.rb: Embed Rdoc style comments. * lib/tempfile.rb: Add length as an alias for size. * lib/tempfile.rb: Add Tempfile#close!() as a shorthand for Tempfile#close(true). * lib/tempfile.rb: Add Tempfile#{unlink,delete}(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@3200 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog11
-rw-r--r--lib/tempfile.rb125
2 files changed, 90 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index 6d53be6a11..f0a3d944ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Mon Dec 23 23:49:36 2002 Akinori MUSHA <knu@iDaemons.org>
+
+ * lib/tempfile.rb: Embed Rdoc style comments.
+
+ * lib/tempfile.rb: Add length as an alias for size.
+
+ * lib/tempfile.rb: Add Tempfile#close!() as a shorthand for
+ Tempfile#close(true).
+
+ * lib/tempfile.rb: Add Tempfile#{unlink,delete}().
+
Sun Dec 22 00:36:43 2002 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/mkmf.rb (create_makefile): accept pure ruby libraries.
diff --git a/lib/tempfile.rb b/lib/tempfile.rb
index 201a0f14f7..e68452fe6a 100644
--- a/lib/tempfile.rb
+++ b/lib/tempfile.rb
@@ -1,48 +1,26 @@
#
-# $Id$
+# tempfile - manipulates temporary files
#
-# This is a class for managing temporary files.
+# $Id$
#
-# o Tempfile::new("basename") creates a temporary file whose name is
-# "basename.pid.n" and opens with mode "w+".
-# o A Tempfile object can be treated as an IO object.
-# o The temporary directory is determined by ENV['TMPDIR'],
-# ENV['TMP'], and ENV['TEMP'] in the order named, and if none of
-# them is available, it is set to /tmp.
-# o When $SAFE > 0, you should specify a directory via the second argument
-# of Tempfile::new(), or it will end up finding an ENV value tainted and
-# pick /tmp. In case you don't have it, an exception will be raised.
-# o Tempfile#close(true) gets the temporary file removed immediately.
-# o Otherwise, the removal is delayed until the object is finalized.
-# o With Tempfile#open, you can reopen the temporary file.
-# o The file mode for the temporary files is 0600.
-# o This library is (considered to be) thread safe.
require 'delegate'
+# A class for managing temporary files. This library is written to be
+# thread safe.
class Tempfile < SimpleDelegator
- Max_try = 10
+ MAX_TRY = 10
@@cleanlist = []
- def Tempfile.callback(data)
- pid = $$
- lambda{
- if pid == $$
- path, tmpfile, cleanlist = *data
-
- print "removing ", path, "..." if $DEBUG
-
- tmpfile.close if tmpfile
-
- # keep this order for thread safeness
- File.unlink(path) if File.exist?(path)
- cleanlist.delete(path) if cleanlist
-
- print "done\n" if $DEBUG
- end
- }
- end
-
+ # Creates a temporary file of mode 0600 in the temporary directory
+ # whose name is basename.pid.n and opens with mode "w+". A Tempfile
+ # object works just like a File object.
+ #
+ # If tmpdir is omitted, the temporary directory is determined by
+ # ENV['TMPDIR'], ENV['TMP'] and and ENV['TEMP'] in the order named.
+ # If none of them is available, or when $SAFE > 0 and the given
+ # tmpdir is tainted, it uses /tmp. (Note that ENV values are
+ # tainted by default)
def initialize(basename, tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp')
if $SAFE > 0 and tmpdir.tainted?
tmpdir = '/tmp'
@@ -64,7 +42,7 @@ class Tempfile < SimpleDelegator
Dir.mkdir(lock)
rescue
failure += 1
- retry if failure < Max_try
+ retry if failure < MAX_TRY
raise "cannot generate tempfile `%s'" % tmpname
ensure
Thread.critical = false
@@ -88,10 +66,7 @@ class Tempfile < SimpleDelegator
Dir.rmdir(lock)
end
- def Tempfile.open(*args)
- Tempfile.new(*args)
- end
-
+ # Opens or reopens the file with mode "r+".
def open
@tmpfile.close if @tmpfile
@tmpfile = File.open(@tmpname, 'r+')
@@ -99,19 +74,50 @@ class Tempfile < SimpleDelegator
__setobj__(@tmpfile)
end
- def close(real=false)
+ def _close # :nodoc:
@tmpfile.close if @tmpfile
@data[1] = @tmpfile = nil
- if real
- @clean_proc.call
- ObjectSpace.undefine_finalizer(self)
+ end
+ protected :_close
+
+ # Closes the file. If the optional flag is true, unlinks the file
+ # after closing.
+ #
+ # 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
end
+ # Closes and unlinks the file.
+ def close!
+ _close
+ @clean_proc.call
+ ObjectSpace.undefine_finalizer(self)
+ end
+
+ # Unlinks the file. On UNIX-like systems, it is often a good idea
+ # to unlink a temporary file immediately after creating and opening
+ # it, because it leaves other programs zero chance to access the
+ # file.
+ def unlink
+ # keep this order for thread safeness
+ File.unlink(@tmpname) if File.exist?(@tmpname)
+ @@cleanlist.delete(@tmpname) if @@cleanlist
+ end
+ alias delete unlink
+
+ # Returns the full path name of the temporary file.
def path
@tmpname
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
@@ -120,6 +126,33 @@ class Tempfile < SimpleDelegator
0
end
end
+ alias length size
+
+ class << self
+ def callback(data) # :nodoc:
+ pid = $$
+ lambda{
+ if pid == $$
+ path, tmpfile, cleanlist = *data
+
+ print "removing ", path, "..." if $DEBUG
+
+ tmpfile.close if tmpfile
+
+ # keep this order for thread safeness
+ File.unlink(path) if File.exist?(path)
+ cleanlist.delete(path) if cleanlist
+
+ print "done\n" if $DEBUG
+ end
+ }
+ end
+
+ # Equivalent to new().
+ def open(*args)
+ new(*args)
+ end
+ end
end
if __FILE__ == $0
@@ -129,5 +162,5 @@ if __FILE__ == $0
f.close
f.open
p f.gets # => "foo\n"
- f.close(true)
+ f.close!
end