summaryrefslogtreecommitdiff
path: root/trunk/lib/tmpdir.rb
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/lib/tmpdir.rb')
-rw-r--r--trunk/lib/tmpdir.rb137
1 files changed, 137 insertions, 0 deletions
diff --git a/trunk/lib/tmpdir.rb b/trunk/lib/tmpdir.rb
new file mode 100644
index 0000000000..2e82aa528e
--- /dev/null
+++ b/trunk/lib/tmpdir.rb
@@ -0,0 +1,137 @@
+#
+# tmpdir - retrieve temporary directory path
+#
+# $Id$
+#
+
+require 'fileutils'
+
+class Dir
+
+ @@systmpdir = '/tmp'
+
+ begin
+ require 'Win32API'
+ CSIDL_LOCAL_APPDATA = 0x001c
+ max_pathlen = 260
+ windir = ' '*(max_pathlen+1)
+ begin
+ getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L')
+ raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0
+ windir = File.expand_path(windir.rstrip)
+ rescue RuntimeError
+ begin
+ getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L')
+ rescue RuntimeError
+ getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L')
+ end
+ len = getdir.call(windir, windir.size)
+ windir = File.expand_path(windir[0, len])
+ end
+ temp = File.join(windir.untaint, 'temp')
+ @@systmpdir = temp if File.directory?(temp) and File.writable?(temp)
+ rescue LoadError
+ end
+
+ ##
+ # Returns the operating system's temporary file path.
+
+ def Dir::tmpdir
+ tmp = '.'
+ if $SAFE > 0
+ tmp = @@systmpdir
+ else
+ for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'],
+ ENV['USERPROFILE'], @@systmpdir, '/tmp']
+ if dir and File.directory?(dir) and File.writable?(dir)
+ tmp = dir
+ break
+ end
+ end
+ File.expand_path(tmp)
+ end
+ end
+
+ # Dir.mktmpdir creates a temporary directory.
+ #
+ # The directory is created with 0700 permission.
+ #
+ # The prefix and suffix of the name of the directory is specified by
+ # the optional first argument, <i>prefix_suffix</i>.
+ # - If it is not specified or nil, "d" is used as the prefix and no suffix is used.
+ # - If it is a string, it is used as the prefix and no suffix is used.
+ # - If it is an array, first element is used as the prefix and second element is used as a suffix.
+ #
+ # Dir.mktmpdir {|dir| dir is ".../d..." }
+ # Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
+ # Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }
+ #
+ # The directory is created under Dir.tmpdir or
+ # the optional second argument <i>tmpdir</i> if non-nil value is given.
+ #
+ # Dir.mktmpdir {|dir| dir is "#{Dir.tmpdir}/d..." }
+ # Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }
+ #
+ # If a block is given,
+ # it is yielded with the path of the directory.
+ # The directory and its contents are removed
+ # using FileUtils.remove_entry_secure before Dir.mktmpdir returns.
+ # The value of the block is returned.
+ #
+ # Dir.mktmpdir {|dir|
+ # # use the directory...
+ # open("#{dir}/foo", "w") { ... }
+ # }
+ #
+ # If a block is not given,
+ # The path of the directory is returned.
+ # In this case, Dir.mktmpdir doesn't remove the directory.
+ #
+ # dir = Dir.mktmpdir
+ # begin
+ # # use the directory...
+ # open("#{dir}/foo", "w") { ... }
+ # ensure
+ # # remove the directory.
+ # FileUtils.remove_entry_secure dir
+ # end
+ #
+ def Dir.mktmpdir(prefix_suffix=nil, tmpdir=nil)
+ case prefix_suffix
+ when nil
+ prefix = "d"
+ suffix = ""
+ when String
+ prefix = prefix_suffix
+ suffix = ""
+ when Array
+ prefix = prefix_suffix[0]
+ suffix = prefix_suffix[1]
+ else
+ raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
+ end
+ tmpdir ||= Dir.tmpdir
+ t = Time.now.strftime("%Y%m%d")
+ n = nil
+ begin
+ path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
+ path << "-#{n}" if n
+ path << suffix
+ Dir.mkdir(path, 0700)
+ rescue Errno::EEXIST
+ n ||= 0
+ n += 1
+ retry
+ end
+
+ if block_given?
+ begin
+ yield path
+ ensure
+ FileUtils.remove_entry_secure path
+ end
+ else
+ path
+ end
+ end
+end