file-temp 1.3.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,21 +1,26 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
2
+ MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
3
3
  cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
4
- MB4XDTE1MDkwMjIwNDkxOFoXDTE2MDkwMTIwNDkxOFowPzERMA8GA1UEAwwIZGpi
4
+ MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
5
5
  ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
6
- bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyTkvXqRp6hLs9eoJOS
7
- Hmi8kRYbq9Vkf15/hMxJpotYMgJVHHWrmDcC5Dye2PbnXjTkKf266Zw0PtT9h+lI
8
- S3ts9HO+vaCFSMwFFZmnWJSpQ3CNw2RcHxjWkk9yF7imEM8Kz9ojhiDXzBetdV6M
9
- gr0lV/alUr7TNVBDngbXEfTWscyXh1qd7xZ4EcOdsDktCe5G45N/o3662tPQvJsi
10
- FOF0CM/KuBsa/HL1/eoEmF4B3EKIRfTHrQ3hu20Kv3RJ88QM4ec2+0dd97uX693O
11
- zv6981fyEg+aXLkxrkViM/tz2qR2ZE0jPhHTREPYeMEgptRkTmWSKAuLVWrJEfgl
12
- DtkCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFEwe
13
- nn6bfJADmuIDiMSOzedOrL+xMB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
14
- bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
15
- ggEBAHmNOCWoDVD75zHFueY0viwGDVP1BNGFC+yXcb7u2GlK+nEMCORqzURbYPf7
16
- tL+/hzmePIRz7i30UM//64GI1NLv9jl7nIwjhPpXpf7/lu2I9hOTsvwSumb5UiKC
17
- /sqBxI3sfj9pr79Wpv4MuikX1XPik7Ncb7NPsJPw06Lvyc3Hkg5X2XpPtLtS+Gr2
18
- wKJnmzb5rIPS1cmsqv0M9LPWflzfwoZ/SpnmhagP+g05p8bRNKjZSA2iImM/GyYZ
19
- EJYzxdPOrx2n6NYR3Hk+vHP0U7UBSveI6+qx+ndQYaeyCn+GRX2PKS9h66YF/Q1V
20
- tGSHgAmcLlkdGgan182qsE/4kKM=
6
+ bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
7
+ A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
8
+ u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
9
+ 75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
10
+ 6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
11
+ iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
12
+ ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
13
+ 74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
14
+ 058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
15
+ HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
16
+ AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
17
+ YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
18
+ /3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
19
+ h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
20
+ 6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
21
+ ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
22
+ 1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
23
+ DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
24
+ ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
25
+ WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
21
26
  -----END CERTIFICATE-----
@@ -2,22 +2,29 @@ require 'rubygems'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'file-temp'
5
- spec.version = '1.3.0'
5
+ spec.version = '1.7.1'
6
6
  spec.author = 'Daniel J. Berger'
7
- spec.license = 'Artistic 2.0'
7
+ spec.license = 'Apache-2.0'
8
8
  spec.email = 'djberg96@gmail.com'
9
9
  spec.homepage = 'http://github.com/djberg96/file-temp'
10
10
  spec.summary = 'An alternative way to generate temp files'
11
- spec.test_file = 'test/test_file_temp.rb'
11
+ spec.test_file = 'spec/file_temp_spec.rb'
12
12
  spec.files = Dir['**/*'].delete_if{ |item| item.include?('git') }
13
13
  spec.cert_chain = Dir['certs/*']
14
14
 
15
- spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
16
-
17
- spec.add_dependency('ffi', '>= 1.0.0')
18
- spec.add_development_dependency('test-unit')
15
+ spec.add_dependency('ffi', '~> 1.1')
16
+ spec.add_development_dependency('rspec', '~> 3.9')
19
17
  spec.add_development_dependency('rake')
20
18
 
19
+ spec.metadata = {
20
+ 'homepage_uri' => 'https://github.com/djberg96/file-temp',
21
+ 'bug_tracker_uri' => 'https://github.com/djberg96/file-temp/issues',
22
+ 'changelog_uri' => 'https://github.com/djberg96/file-temp/blob/master/CHANGES.md',
23
+ 'documentation_uri' => 'https://github.com/djberg96/file-temp/wiki',
24
+ 'source_code_uri' => 'https://github.com/djberg96/file-temp',
25
+ 'wiki_uri' => 'https://github.com/djberg96/file-temp/wiki'
26
+ }
27
+
21
28
  spec.description = <<-EOF
22
29
  The file-temp library provides an alternative approach to generating
23
30
  temporary files. Features included improved security, a superior
@@ -2,17 +2,14 @@ require 'java'
2
2
  import java.lang.System
3
3
 
4
4
  class File::Temp < File
5
- # The version of the file-temp library.
6
- VERSION = '1.3.0'
7
-
8
5
  # The temporary directory used on MS Windows or Unix.
9
6
  TMPDIR = java.lang.System.getProperties["java.io.tmpdir"]
10
7
 
11
8
  # The name of the temporary file.
12
9
  attr_reader :path
13
10
 
14
- # Creates a new, anonymous, temporary file in your File::Temp::TMPDIR
15
- # directory.
11
+ # Creates a new, anonymous, temporary file in your system's temporary
12
+ # directory, or whichever directory you specify.
16
13
  #
17
14
  # If the +delete+ option is set to true (the default) then the temporary file
18
15
  # will be deleted automatically as soon as all references to it are closed.
@@ -30,11 +27,11 @@ class File::Temp < File
30
27
  #
31
28
  # Example:
32
29
  #
33
- # fh = File::Temp.new(true, 'rb_file_temp_XXXXXX') => file
30
+ # fh = File::Temp.new(delete: true, template: 'rb_file_temp_XXXXXX')
34
31
  # fh.puts 'hello world'
35
32
  # fh.close
36
33
  #
37
- def initialize(delete = true, template = 'rb_file_temp_XXXXXX')
34
+ def initialize(delete: true, template: 'rb_file_temp_XXXXXX', directory: TMPDIR, **options)
38
35
  raise TypeError unless template.is_a?(String)
39
36
 
40
37
  # Since Java uses a GUID extension to generate a unique file name
@@ -44,27 +41,27 @@ class File::Temp < File
44
41
  # For consistency between implementations, convert errors here
45
42
  # to Errno::EINVAL.
46
43
  begin
47
- @file = java.io.File.createTempFile(template, nil)
44
+ @file = java.io.File.createTempFile(template, nil, java.io.File.new(directory))
48
45
  rescue NativeException => err
49
46
  raise SystemCallError.new(22), template # 22 is EINVAL
50
47
  end
51
48
 
52
49
  @file.deleteOnExit if delete
50
+ options[:mode] ||= 'wb+'
53
51
 
54
52
  path = @file.getName
55
- super(path, 'wb+')
53
+ super(path, **options)
56
54
 
57
55
  @path = path unless delete
58
56
  end
59
57
 
60
- # Generates a unique file name.
58
+ # Generates a unique file name based on your tmpdir, or whichever
59
+ # directory you specify.
61
60
  #
62
- def self.temp_name
63
- file = java.io.File.createTempFile('rb_file_temp_', nil)
61
+ def self.temp_name(directory = TMPDIR)
62
+ file = java.io.File.createTempFile('rb_file_temp_', nil, java.io.File.new(directory))
64
63
  file.deleteOnExit
65
- name = file.getName
66
- file.finalize
67
- name
64
+ directory + file.getName
68
65
  end
69
66
 
70
67
  # Identical to the File#close method except that we also finalize
@@ -1,3 +1,8 @@
1
+ class File::Temp < File
2
+ # The version of the file-temp library
3
+ VERSION = '1.7.1'.freeze
4
+ end
5
+
1
6
  if RUBY_PLATFORM == 'java'
2
7
  require_relative 'java/temp'
3
8
  else
@@ -23,22 +23,19 @@ class File::Temp < File
23
23
 
24
24
  # :startdoc:
25
25
 
26
- # The version of the file-temp library.
27
- VERSION = '1.3.0'
28
-
29
- # The temporary directory used on MS Windows or Unix.
26
+ # The temporary directory used on MS Windows or Unix by default.
30
27
  TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['TMPDIR'] || Dir.tmpdir
31
28
 
32
29
  # The name of the temporary file. Set to nil if the +delete+ option to the
33
30
  # constructor is true.
34
31
  attr_reader :path
35
32
 
36
- # Creates a new, anonymous, temporary file in your File::Temp::TMPDIR
37
- # directory
33
+ # Creates a new, anonymous, temporary file in your tmpdir, or whichever
34
+ # directory you specifiy.
38
35
  #
39
36
  # If the +delete+ option is set to true (the default) then the temporary file
40
37
  # will be deleted automatically as soon as all references to it are closed.
41
- # Otherwise, the file will live on in your File::Temp::TMPDIR path.
38
+ # Otherwise, the file will live on in your tmpdir path.
42
39
  #
43
40
  # If the +delete+ option is set to false, then the file is not deleted. In
44
41
  # addition, you can supply a string +template+ that the system replaces with
@@ -50,48 +47,53 @@ class File::Temp < File
50
47
  #
51
48
  # Example:
52
49
  #
53
- # fh = File::Temp.new(true, 'rb_file_temp_XXXXXX') => file
50
+ # fh = File::Temp.new(delete: true, template: 'rb_file_temp_XXXXXX') => file
54
51
  # fh.puts 'hello world'
55
52
  # fh.close
56
53
  #
57
- def initialize(delete = true, template = 'rb_file_temp_XXXXXX')
54
+ def initialize(delete: true, template: 'rb_file_temp_XXXXXX', directory: TMPDIR, **options)
58
55
  @fptr = nil
59
56
 
60
57
  if delete
61
58
  @fptr = tmpfile()
59
+ raise SystemCallError.new('tmpfile', FFI.errno) if @fptr.null?
62
60
  fd = _fileno(@fptr)
63
61
  else
64
62
  begin
65
63
  omask = File.umask(077)
66
-
67
64
  ptr = FFI::MemoryPointer.from_string(template)
68
-
69
65
  str = mktemp(ptr)
70
66
 
71
67
  if str.nil? || str.empty?
72
68
  raise SystemCallError.new('mktemp', FFI.errno)
73
69
  end
74
70
 
75
- @path = File.join(TMPDIR, ptr.read_string)
71
+ @path = File.join(directory, ptr.read_string)
76
72
  ensure
77
73
  File.umask(omask)
78
74
  end
79
75
  end
80
76
 
77
+ options[:mode] ||= 'wb+'
78
+
81
79
  if delete
82
- super(fd, 'wb+')
80
+ super(fd, **options)
83
81
  else
84
- super(@path, 'wb+')
82
+ super(@path, **options)
85
83
  end
86
84
  end
87
85
 
88
- # The close method was overridden to ensure the internal file pointer we
89
- # created in the constructor is closed. It is otherwise identical to the
90
- # File#close method.
86
+ # The close method was overridden to ensure the internal file pointer that we
87
+ # potentially created in the constructor is closed. It is otherwise identical
88
+ # to the File#close method.
89
+ #--
90
+ # This is probably unnecessary since Ruby will close the fd, and in reality
91
+ # the fclose function probably fails with an Errno::EBADF. Consequently
92
+ # I will let it silently fail as a no-op.
91
93
  #
92
94
  def close
93
95
  super
94
- fclose(@fptr) if @fptr
96
+ fclose(@fptr) if @fptr && !@fptr.null?
95
97
  end
96
98
 
97
99
  # Generates a unique file name.
@@ -53,10 +53,7 @@ class File::Temp < File
53
53
 
54
54
  # :startdoc:
55
55
 
56
- # The version of the file-temp library.
57
- VERSION = '1.3.0'
58
-
59
- # The temporary directory used on MS Windows or Unix.
56
+ # The temporary directory used on MS Windows or Unix by default.
60
57
  TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['USERPROFILE'] || Dir.tmpdir
61
58
 
62
59
  # The name of the temporary file. Set to nil if the +delete+ option to the
@@ -64,7 +61,7 @@ class File::Temp < File
64
61
  attr_reader :path
65
62
 
66
63
  # Creates a new, anonymous, temporary file in your File::Temp::TMPDIR
67
- # directory
64
+ # directory, or whichever directory you specify.
68
65
  #
69
66
  # If the +delete+ option is set to true (the default) then the temporary file
70
67
  # will be deleted automatically as soon as all references to it are closed.
@@ -80,11 +77,11 @@ class File::Temp < File
80
77
  #
81
78
  # Example:
82
79
  #
83
- # fh = File::Temp.new(true, 'rb_file_temp_XXXXXX') => file
80
+ # fh = File::Temp.new(delete: true, template: 'rb_file_temp_XXXXXX')
84
81
  # fh.puts 'hello world'
85
82
  # fh.close
86
83
  #
87
- def initialize(delete = true, template = 'rb_file_temp_XXXXXX')
84
+ def initialize(delete: true, template: 'rb_file_temp_XXXXXX', directory: TMPDIR, **options)
88
85
  @fptr = nil
89
86
 
90
87
  if delete
@@ -93,24 +90,24 @@ class File::Temp < File
93
90
  else
94
91
  begin
95
92
  omask = File.umask(077)
96
-
97
93
  ptr = FFI::MemoryPointer.from_string(template)
98
-
99
94
  errno = mktemp_s(ptr, ptr.size)
100
95
 
101
96
  raise SystemCallError.new('mktemp_s', errno) if errno != 0
102
97
 
103
- @path = File.join(TMPDIR, ptr.read_string)
98
+ @path = File.join(directory, ptr.read_string)
104
99
  @path.tr!(File::SEPARATOR, File::ALT_SEPARATOR)
105
100
  ensure
106
101
  File.umask(omask)
107
102
  end
108
103
  end
109
104
 
105
+ options[:mode] ||= 'wb+'
106
+
110
107
  if delete
111
- super(fd, 'wb+')
108
+ super(fd, **options)
112
109
  else
113
- super(@path, 'wb+')
110
+ super(@path, **options)
114
111
  end
115
112
  end
116
113
 
@@ -123,20 +120,21 @@ class File::Temp < File
123
120
  fclose(@fptr) if @fptr
124
121
  end
125
122
 
126
- # Generates a unique file name.
123
+ # Generates a unique file name based on your default temporary directory,
124
+ # or whichever directory you specify.
127
125
  #
128
126
  # Note that a file is not actually generated on the filesystem.
129
127
  #--
130
128
  # NOTE: One quirk of the Windows function is that, after the first call, it
131
129
  # adds a file extension of sequential numbers in base 32, e.g. .1-.1vvvvvu.
132
130
  #
133
- def self.temp_name
131
+ def self.temp_name(directory: TMPDIR)
134
132
  ptr = FFI::MemoryPointer.new(:char, 1024)
135
133
  errno = tmpnam_s(ptr, ptr.size)
136
134
 
137
135
  raise SystemCallError.new('tmpnam_s', errno) if errno != 0
138
136
 
139
- TMPDIR + ptr.read_string + 'tmp'
137
+ directory + ptr.read_string + 'tmp'
140
138
  end
141
139
 
142
140
  private
@@ -0,0 +1,159 @@
1
+ ######################################################################
2
+ # file_temp_spec.rb
3
+ #
4
+ # Test suite for the file-temp library. These tests should be run
5
+ # via the 'rake spec' task.
6
+ ######################################################################
7
+ require 'rspec'
8
+ require 'file/temp'
9
+
10
+ RSpec.describe File::Temp do
11
+ let(:windows) { File::ALT_SEPARATOR }
12
+ let(:osx) { RbConfig::CONFIG['host_os'] =~ /darwin/i }
13
+
14
+ before do
15
+ @dir = File::Temp::TMPDIR
16
+ @template = 'file-temp-test-XXXXX'
17
+ @fh = nil
18
+
19
+ # Because Dir[] doesn't work right with backslashes
20
+ @dir = @dir.tr("\\", "/") if windows
21
+ end
22
+
23
+ context "constants" do
24
+ example "library version is set to expected value" do
25
+ expect( File::Temp::VERSION).to eq('1.7.1')
26
+ expect(File::Temp::VERSION).to be_frozen
27
+ end
28
+
29
+ example "TMPDIR constant is defined" do
30
+ expect(File::Temp::TMPDIR).to be_kind_of(String)
31
+ expect(File::Temp::TMPDIR.size).to be > 0
32
+ end
33
+ end
34
+
35
+ context "threads" do
36
+ example "library works as expected with multiple threads" do
37
+ threads = []
38
+ expect{ 100.times{ threads << Thread.new{ File::Temp.new }}}.not_to raise_error
39
+ expect{ threads.each{ |t| t.join }.not_to raise_error }
40
+ end
41
+ end
42
+
43
+ context "constructor" do
44
+ example "constructor works as expected with default auto delete option" do
45
+ expect{
46
+ @fh = File::Temp.new
47
+ @fh.print "hello"
48
+ @fh.close
49
+ }.not_to raise_error
50
+ end
51
+
52
+ example "constructor works as expected with false auto delete option" do
53
+ expect{
54
+ @fh = File::Temp.new(:delete => false)
55
+ @fh.print "hello"
56
+ @fh.close
57
+ }.not_to raise_error
58
+ end
59
+
60
+ example "constructor accepts and uses an optional template as expected" do
61
+ expect{ File::Temp.new(:delete => false, :template => 'temp_foo_XXXXXX').close }.not_to raise_error
62
+ expect(Dir["#{@dir}/temp_foo*"].length).to be >= 1
63
+ end
64
+
65
+ example "constructor with false auto delete and block works as expected" do
66
+ expect{
67
+ File::Temp.open(:delete => false, :template => 'temp_foo_XXXXXX'){ |fh| fh.puts "hello" }
68
+ }.not_to raise_error
69
+ expect(Dir["#{@dir}/temp_foo*"].length).to be >= 1
70
+ end
71
+
72
+ example "other arguments are treated as file option arguments" do
73
+ expect{
74
+ @fh = File::Temp.new(
75
+ :delete => true,
76
+ :template => 'temp_bar_XXXXX',
77
+ :directory => Dir.pwd,
78
+ :mode => 'xb'
79
+ )
80
+ }.to raise_error(ArgumentError, /invalid access mode/)
81
+ end
82
+ end
83
+
84
+ context "template" do
85
+ example "template argument must be a string" do
86
+ expect{ @fh = File::Temp.new(:delete => false, :template => 1) }.to raise_error(TypeError)
87
+ end
88
+
89
+ example "an error is raised if a custom template is invalid" do
90
+ skip "skipped on OSX" if osx
91
+ expect{ File::Temp.new(:delete => false, :template => 'xx') }.to raise_error(Errno::EINVAL)
92
+ end
93
+ end
94
+
95
+ context "temp_name" do
96
+ example "temp_name basic functionality" do
97
+ expect(File::Temp).to respond_to(:temp_name)
98
+ expect{ File::Temp.temp_name }.not_to raise_error
99
+ expect(File::Temp.temp_name).to be_kind_of(String)
100
+ end
101
+
102
+ example "temp_name returns expected value" do
103
+ if windows
104
+ expect( File.extname(File::Temp.temp_name)).to match(/^.*?\d*?tmp/)
105
+ else
106
+ expect( File.extname(File::Temp.temp_name)).to eq('.tmp')
107
+ end
108
+ end
109
+ end
110
+
111
+ context "path" do
112
+ example "temp path basic functionality" do
113
+ @fh = File::Temp.new
114
+ expect(@fh).to respond_to(:path)
115
+ end
116
+
117
+ example "temp path is nil if delete option is true" do
118
+ @fh = File::Temp.new
119
+ expect(@fh.path).to be_nil
120
+ end
121
+
122
+ example "temp path is not nil if delete option is false" do
123
+ @fh = File::Temp.new(delete: false)
124
+ expect(@fh.path).not_to be_nil
125
+ end
126
+ end
127
+
128
+ context "ffi" do
129
+ example "ffi functions are private" do
130
+ methods = File::Temp.methods(false).map(&:to_s)
131
+ expect(methods).not_to include('_fileno')
132
+ expect(methods).not_to include('mkstemp')
133
+ expect(methods).not_to include('_umask')
134
+ expect(methods).not_to include('fclose')
135
+ expect(methods).not_to include('strerror')
136
+ expect(methods).not_to include('tmpnam')
137
+ expect(methods).not_to include('CloseHandle')
138
+ expect(methods).not_to include('CreateFileA')
139
+ expect(methods).not_to include('DeleteFileA')
140
+ expect(methods).not_to include('GetTempPathA')
141
+ expect(methods).not_to include('GetTempFileNameA')
142
+ end
143
+ end
144
+
145
+ after do
146
+ @dir = nil
147
+ @template = nil
148
+ @fh.close if @fh && !@fh.closed?
149
+ @fh = nil
150
+
151
+ Dir["temp_*"].each{ |f| File.delete(f) }
152
+ Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
153
+
154
+ Dir.chdir(File::Temp::TMPDIR) do
155
+ Dir["temp_*"].each{ |f| File.delete(f) }
156
+ Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
157
+ end
158
+ end
159
+ end