aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tmpdir.rb
blob: ada9ed5544ebe7648a3126d5730679f2792c2201 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#
# tmpdir - retrieve temporary directory path
#
# $Id$
#

require 'fileutils'

class Dir

  @@systmpdir = '/tmp'

  begin
    require 'Win32API'
    max_pathlen = 260
    windir = ' '*(max_pathlen+1)
    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])
    temp = File.join(windir, '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
    end
    File.expand_path(tmp)
  end

  # Dir.mktmpdir creates a temporary directory.
  #
  # The directory is created with 0700 permission.
  # The name of the directory is prefixed
  # with <i>prefix</i> argument.
  # If <i>prefix</i> is not given,
  # the prefix "d" is used.
  #
  # The directory is created under Dir.tmpdir or
  # the optional second argument <i>tmpdir</i> if given.
  #
  # If a block is given,
  # it is yielded with the path of the directory.
  # The directory is removed 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="d", tmpdir=nil)
    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
      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