file-temp 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES +63 -50
- data/MANIFEST +9 -7
- data/README +61 -56
- data/Rakefile +66 -61
- data/file-temp.gemspec +27 -26
- data/lib/file/temp.rb +5 -254
- data/lib/file/temp_c.rb +254 -0
- data/lib/file/temp_java.rb +76 -0
- data/test/test_file_temp.rb +135 -120
- metadata +46 -25
data/lib/file/temp_c.rb
ADDED
@@ -0,0 +1,254 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
class File::Temp < File
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib FFI::Library::LIBC
|
7
|
+
|
8
|
+
# :stopdoc:
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
if File::ALT_SEPARATOR
|
13
|
+
attach_function :_close, [:int], :int
|
14
|
+
attach_function :fclose, [:pointer], :int
|
15
|
+
attach_function :_fdopen, [:int, :string], :pointer
|
16
|
+
attach_function :_fileno, [:pointer], :int
|
17
|
+
attach_function :_get_errno, [:pointer], :int
|
18
|
+
attach_function :_open, [:string, :int, :int], :int
|
19
|
+
attach_function :_open_osfhandle, [:long, :int], :int
|
20
|
+
attach_function :tmpnam_s, [:pointer, :size_t], :int
|
21
|
+
attach_function :mktemp_s, :_mktemp_s, [:pointer, :size_t], :int
|
22
|
+
|
23
|
+
private_class_method :_close, :_fdopen, :_get_errno, :_open
|
24
|
+
private_class_method :_open_osfhandle, :mktemp_s, :tmpnam_s
|
25
|
+
|
26
|
+
ffi_lib :kernel32
|
27
|
+
|
28
|
+
attach_function :CloseHandle, [:long], :bool
|
29
|
+
attach_function :CreateFileW, [:buffer_in, :ulong, :ulong, :pointer, :ulong, :ulong, :ulong], :long
|
30
|
+
attach_function :DeleteFileW, [:string], :bool
|
31
|
+
attach_function :GetTempPathW, [:ulong, :buffer_out], :ulong
|
32
|
+
attach_function :GetTempFileNameW, [:buffer_in, :string, :uint, :buffer_out], :uint
|
33
|
+
|
34
|
+
private_class_method :_close, :_fdopen, :_open, :_open_osfhandle
|
35
|
+
private_class_method :CloseHandle, :CreateFileW, :DeleteFileW
|
36
|
+
private_class_method :GetTempPathW, :GetTempFileNameW
|
37
|
+
|
38
|
+
S_IWRITE = 128
|
39
|
+
S_IREAD = 256
|
40
|
+
BINARY = 0x8000
|
41
|
+
SHORT_LIVED = 0x1000
|
42
|
+
GENERIC_READ = 0x80000000
|
43
|
+
GENERIC_WRITE = 0x40000000
|
44
|
+
CREATE_ALWAYS = 2
|
45
|
+
|
46
|
+
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
|
47
|
+
FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000
|
48
|
+
|
49
|
+
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
50
|
+
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
|
51
|
+
INVALID_HANDLE_VALUE = -1
|
52
|
+
else
|
53
|
+
attach_function :fclose, [:pointer], :int
|
54
|
+
attach_function :_fileno, :fileno, [:pointer], :int
|
55
|
+
attach_function :strerror, [:int], :string
|
56
|
+
attach_function :tmpfile, [], :pointer
|
57
|
+
attach_function :tmpnam, [:pointer], :string
|
58
|
+
attach_function :mktemp, [:pointer], :string
|
59
|
+
|
60
|
+
private_class_method :mktemp, :strerror, :tmpfile, :tmpnam
|
61
|
+
end
|
62
|
+
|
63
|
+
private_class_method :fclose, :_fileno
|
64
|
+
|
65
|
+
public
|
66
|
+
|
67
|
+
# :startdoc:
|
68
|
+
|
69
|
+
# The version of the file-temp library.
|
70
|
+
VERSION = '1.2.1'
|
71
|
+
|
72
|
+
# The temporary directory used on MS Windows or Unix.
|
73
|
+
if File::ALT_SEPARATOR
|
74
|
+
TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['USERPROFILE'] || Dir.tmpdir
|
75
|
+
else
|
76
|
+
TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['TMPDIR'] || Dir.tmpdir
|
77
|
+
end
|
78
|
+
|
79
|
+
# The name of the temporary file. Set to nil if the +delete+ option to the
|
80
|
+
# constructor is true.
|
81
|
+
attr_reader :path
|
82
|
+
|
83
|
+
# Creates a new, anonymous, temporary file in your File::Temp::TMPDIR
|
84
|
+
# directory
|
85
|
+
#
|
86
|
+
# If the +delete+ option is set to true (the default) then the temporary file
|
87
|
+
# will be deleted automatically as soon as all references to it are closed.
|
88
|
+
# Otherwise, the file will live on in your File::Temp::TMPDIR path.
|
89
|
+
#
|
90
|
+
# If the +delete+ option is set to false, then the file is not deleted. In
|
91
|
+
# addition, you can supply a string +template+ that the system replaces with
|
92
|
+
# a unique filename. This template should end with 3 to 6 'X' characters.
|
93
|
+
# The default template is 'rb_file_temp_XXXXXX'. In this case the temporary
|
94
|
+
# file lives in the directory where it was created.
|
95
|
+
#
|
96
|
+
# The +template+ argument is ignored if the +delete+ argument is true.
|
97
|
+
#
|
98
|
+
# Example:
|
99
|
+
#
|
100
|
+
# fh = File::Temp.new(true, 'rb_file_temp_XXXXXX') => file
|
101
|
+
# fh.puts 'hello world'
|
102
|
+
# fh.close
|
103
|
+
#
|
104
|
+
def initialize(delete = true, template = 'rb_file_temp_XXXXXX')
|
105
|
+
@fptr = nil
|
106
|
+
|
107
|
+
if delete
|
108
|
+
@fptr = tmpfile()
|
109
|
+
fd = _fileno(@fptr)
|
110
|
+
else
|
111
|
+
begin
|
112
|
+
omask = File.umask(077)
|
113
|
+
|
114
|
+
ptr = FFI::MemoryPointer.from_string(template)
|
115
|
+
|
116
|
+
if File::ALT_SEPARATOR
|
117
|
+
errno = mktemp_s(ptr, ptr.size)
|
118
|
+
|
119
|
+
raise SystemCallError.new('mktemp_s', errno) if errno != 0
|
120
|
+
else
|
121
|
+
str = mktemp(ptr)
|
122
|
+
|
123
|
+
if str.nil? || str.empty?
|
124
|
+
raise SystemCallError.new('mktemp', FFI.errno)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
@path = File.join(TMPDIR, ptr.read_string)
|
129
|
+
@path.tr!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
|
130
|
+
ensure
|
131
|
+
File.umask(omask)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
if delete
|
136
|
+
super(fd, 'wb+')
|
137
|
+
else
|
138
|
+
super(@path, 'wb+')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# The close method was overridden to ensure the internal file pointer we
|
143
|
+
# created in the constructor is closed. It is otherwise identical to the
|
144
|
+
# File#close method.
|
145
|
+
#
|
146
|
+
def close
|
147
|
+
super
|
148
|
+
fclose(@fptr) if @fptr
|
149
|
+
end
|
150
|
+
|
151
|
+
# Generates a unique file name.
|
152
|
+
#
|
153
|
+
# Note that a file is not actually generated on the filesystem.
|
154
|
+
#--
|
155
|
+
# NOTE: One quirk of the Windows function is that, after the first call, it
|
156
|
+
# adds a file extension of sequential numbers in base 32, e.g. .1-.1vvvvvu.
|
157
|
+
#
|
158
|
+
def self.temp_name
|
159
|
+
if File::ALT_SEPARATOR
|
160
|
+
ptr = FFI::MemoryPointer.new(:char, 1024)
|
161
|
+
errno = tmpnam_s(ptr, ptr.size)
|
162
|
+
|
163
|
+
raise SystemCallError.new('tmpnam_s', errno) if errno != 0
|
164
|
+
|
165
|
+
TMPDIR + ptr.read_string + 'tmp'
|
166
|
+
else
|
167
|
+
tmpnam(nil) << '.tmp'
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
# For those times when we want the posix errno rather than a formatted string.
|
174
|
+
# This is necessary because FFI.errno appears to be using GetLastError() which
|
175
|
+
# does not always match what _get_errno() returns.
|
176
|
+
#
|
177
|
+
def get_posix_errno
|
178
|
+
if File::ALT_SEPARATOR
|
179
|
+
ptr = FFI::MemoryPointer.new(:int)
|
180
|
+
_get_errno(ptr)
|
181
|
+
ptr.read_int
|
182
|
+
else
|
183
|
+
FFI.errno
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
if File::ALT_SEPARATOR
|
188
|
+
# Simple wrapper around the GetTempPath function.
|
189
|
+
#
|
190
|
+
def get_temp_path
|
191
|
+
buf = 0.chr * 1024
|
192
|
+
buf.encode!("UTF-16LE")
|
193
|
+
|
194
|
+
if GetTempPathW(buf.size, buf) == 0
|
195
|
+
raise SystemCallError, FFI.errno, 'GetTempPathW'
|
196
|
+
end
|
197
|
+
|
198
|
+
buf.strip.chop # remove trailing slash
|
199
|
+
end
|
200
|
+
|
201
|
+
# The version of tmpfile() implemented by Microsoft is unacceptable.
|
202
|
+
# It attempts to write to C:\ (root) instead of a temporary directory.
|
203
|
+
# This is not only bad behavior, it won't work on Windows 7 and later
|
204
|
+
# without admin rights due to security restrictions.
|
205
|
+
#
|
206
|
+
# This is a custom implementation based on some code from the Cairo
|
207
|
+
# project.
|
208
|
+
#
|
209
|
+
def tmpfile
|
210
|
+
file_name = get_temp_path()
|
211
|
+
buf = 0.chr * 1024
|
212
|
+
buf.encode!("UTF-16LE")
|
213
|
+
|
214
|
+
if GetTempFileNameW(file_name, 'rb_', 0, buf) == 0
|
215
|
+
raise SystemCallError, FFI.errno, 'GetTempFileNameW'
|
216
|
+
end
|
217
|
+
|
218
|
+
file_name = buf.strip
|
219
|
+
|
220
|
+
handle = CreateFileW(
|
221
|
+
file_name,
|
222
|
+
GENERIC_READ | GENERIC_WRITE,
|
223
|
+
0,
|
224
|
+
nil,
|
225
|
+
CREATE_ALWAYS,
|
226
|
+
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
|
227
|
+
0
|
228
|
+
)
|
229
|
+
|
230
|
+
if handle == INVALID_HANDLE_VALUE
|
231
|
+
error = FFI.errno
|
232
|
+
DeleteFileW(file_name)
|
233
|
+
raise SystemCallError.new('CreateFileW', error)
|
234
|
+
end
|
235
|
+
|
236
|
+
fd = _open_osfhandle(handle, 0)
|
237
|
+
|
238
|
+
if fd < 0
|
239
|
+
CloseHandle(handle)
|
240
|
+
raise SystemCallError, get_posix_errno, '_open_osfhandle'
|
241
|
+
end
|
242
|
+
|
243
|
+
fp = _fdopen(fd, 'w+b')
|
244
|
+
|
245
|
+
if fp.nil?
|
246
|
+
_close(fd)
|
247
|
+
CloseHandle(handle)
|
248
|
+
raise SystemCallError, get_posix_errno, 'fdopen'
|
249
|
+
end
|
250
|
+
|
251
|
+
fp
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'java'
|
2
|
+
import java.lang.System
|
3
|
+
|
4
|
+
class File::Temp < File
|
5
|
+
# The version of the file-temp library.
|
6
|
+
VERSION = '1.2.1'
|
7
|
+
|
8
|
+
# The temporary directory used on MS Windows or Unix.
|
9
|
+
TMPDIR = java.lang.System.getProperties["java.io.tmpdir"]
|
10
|
+
|
11
|
+
# The name of the temporary file.
|
12
|
+
attr_reader :path
|
13
|
+
|
14
|
+
# Creates a new, anonymous, temporary file in your File::Temp::TMPDIR
|
15
|
+
# directory.
|
16
|
+
#
|
17
|
+
# If the +delete+ option is set to true (the default) then the temporary file
|
18
|
+
# will be deleted automatically as soon as all references to it are closed.
|
19
|
+
# Otherwise, the file will live on in your File::Temp::TMPDIR path.
|
20
|
+
#
|
21
|
+
# If the +delete+ option is set to false, then the file is not deleted. In
|
22
|
+
# addition, you can supply a string +template+ that the system replaces with
|
23
|
+
# a unique filename. This template should end with 3 to 6 'X' characters.
|
24
|
+
# The default template is 'rb_file_temp_XXXXXX'. In this case the temporary
|
25
|
+
# file lives in the directory where it was created.
|
26
|
+
#
|
27
|
+
# Note that when using JRuby the template naming is not as strict, and the
|
28
|
+
# trailing 'X' characters are simply replaced with the GUID that Java
|
29
|
+
# generates for unique file names.
|
30
|
+
#
|
31
|
+
# Example:
|
32
|
+
#
|
33
|
+
# fh = File::Temp.new(true, 'rb_file_temp_XXXXXX') => file
|
34
|
+
# fh.puts 'hello world'
|
35
|
+
# fh.close
|
36
|
+
#
|
37
|
+
def initialize(delete = true, template = 'rb_file_temp_XXXXXX')
|
38
|
+
raise TypeError unless template.is_a?(String)
|
39
|
+
|
40
|
+
# Since Java uses a GUID extension to generate a unique file name
|
41
|
+
# we'll simply chop off the 'X' characters and let Java do the rest.
|
42
|
+
template = template.sub(/_X{1,6}/, '_')
|
43
|
+
|
44
|
+
# For consistency between implementations, convert errors here
|
45
|
+
# to Errno::EINVAL.
|
46
|
+
begin
|
47
|
+
@file = java.io.File.createTempFile(template, nil)
|
48
|
+
rescue NativeException => err
|
49
|
+
raise SystemCallError.new(22), template # 22 is EINVAL
|
50
|
+
end
|
51
|
+
|
52
|
+
@file.deleteOnExit if delete
|
53
|
+
|
54
|
+
@path = @file.getName
|
55
|
+
|
56
|
+
super(@path, 'wb+')
|
57
|
+
end
|
58
|
+
|
59
|
+
# Generates a unique file name.
|
60
|
+
#
|
61
|
+
def self.temp_name
|
62
|
+
file = java.io.File.createTempFile('rb_file_temp_', nil)
|
63
|
+
file.deleteOnExit
|
64
|
+
name = file.getName
|
65
|
+
file.finalize
|
66
|
+
name
|
67
|
+
end
|
68
|
+
|
69
|
+
# Identical to the File#close method except that we also finalize
|
70
|
+
# the underlying Java File object.
|
71
|
+
#
|
72
|
+
def close
|
73
|
+
super
|
74
|
+
@file.finalize
|
75
|
+
end
|
76
|
+
end
|
data/test/test_file_temp.rb
CHANGED
@@ -1,120 +1,135 @@
|
|
1
|
-
######################################################################
|
2
|
-
# test_file_temp.rb
|
3
|
-
#
|
4
|
-
# Test suite for the file-temp library. These tests should be run
|
5
|
-
# via the 'rake test' task.
|
6
|
-
######################################################################
|
7
|
-
require 'rubygems'
|
8
|
-
require 'test-unit'
|
9
|
-
require 'file/temp'
|
10
|
-
|
11
|
-
class TC_File_Temp < Test::Unit::TestCase
|
12
|
-
WINDOWS = File::ALT_SEPARATOR
|
13
|
-
|
14
|
-
def setup
|
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
|
-
|
24
|
-
assert_equal('1.2.
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
assert_nothing_raised{ threads.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
assert_nothing_raised{
|
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
|
-
assert_respond_to(
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
|
1
|
+
######################################################################
|
2
|
+
# test_file_temp.rb
|
3
|
+
#
|
4
|
+
# Test suite for the file-temp library. These tests should be run
|
5
|
+
# via the 'rake test' task.
|
6
|
+
######################################################################
|
7
|
+
require 'rubygems'
|
8
|
+
require 'test-unit'
|
9
|
+
require 'file/temp'
|
10
|
+
|
11
|
+
class TC_File_Temp < Test::Unit::TestCase
|
12
|
+
WINDOWS = File::ALT_SEPARATOR
|
13
|
+
|
14
|
+
def setup
|
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
|
+
test "library version is set to expected value" do
|
24
|
+
assert_equal('1.2.1', File::Temp::VERSION)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Fails with JRuby, not sure why.
|
28
|
+
test "library works as expected with multiple threads" do
|
29
|
+
threads = []
|
30
|
+
assert_nothing_raised{ 100.times{ threads << Thread.new{ File::Temp.new }}}
|
31
|
+
assert_nothing_raised{ threads.each{ |t| t.join } }
|
32
|
+
end
|
33
|
+
|
34
|
+
test "TMPDIR constant is defined" do
|
35
|
+
assert_not_nil(File::Temp::TMPDIR)
|
36
|
+
assert_kind_of(String, File::Temp::TMPDIR)
|
37
|
+
end
|
38
|
+
|
39
|
+
test "constructor works as expected with default auto delete option" do
|
40
|
+
assert_nothing_raised{
|
41
|
+
@fh = File::Temp.new
|
42
|
+
@fh.print "hello"
|
43
|
+
@fh.close
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
test "constructor works as expected with false auto delete option" do
|
48
|
+
assert_nothing_raised{
|
49
|
+
@fh = File::Temp.new(false)
|
50
|
+
@fh.print "hello"
|
51
|
+
@fh.close
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
test "constructor accepts and uses an optional template as expected" do
|
56
|
+
assert_nothing_raised{ File::Temp.new(false, 'temp_foo_XXXXXX').close }
|
57
|
+
assert_true(Dir["#{@dir}/temp_foo*"].length >= 1)
|
58
|
+
end
|
59
|
+
|
60
|
+
test "constructor with false auto delete and block works as expected" do
|
61
|
+
assert_nothing_raised{ File::Temp.open(false, 'temp_foo_XXXXXX'){ |fh| fh.puts "hello" } }
|
62
|
+
assert_true(Dir["#{@dir}/temp_foo*"].length >= 1)
|
63
|
+
end
|
64
|
+
|
65
|
+
test "second argument to constructor must be a string" do
|
66
|
+
assert_raise(TypeError, ArgumentError){ @fh = File::Temp.new(false, 1) }
|
67
|
+
end
|
68
|
+
|
69
|
+
test "an error is raised if a custom template is invalid" do
|
70
|
+
assert_raise(Errno::EINVAL){ File::Temp.new(false, 'xx') }
|
71
|
+
end
|
72
|
+
|
73
|
+
test "constructor accepts a maximum of two arguments" do
|
74
|
+
assert_raise(ArgumentError){ @fh = File::Temp.new(true, 'temp_bar_XXXXX', 1) }
|
75
|
+
end
|
76
|
+
|
77
|
+
test "temp_name basic functionality" do
|
78
|
+
assert_respond_to(File::Temp, :temp_name)
|
79
|
+
assert_nothing_raised{ File::Temp.temp_name }
|
80
|
+
assert_kind_of(String, File::Temp.temp_name)
|
81
|
+
end
|
82
|
+
|
83
|
+
test "temp_name returns expected value" do
|
84
|
+
if File::ALT_SEPARATOR
|
85
|
+
assert_match(/^.*?\d*?tmp/, File.extname(File::Temp.temp_name))
|
86
|
+
else
|
87
|
+
assert_equal('.tmp', File.extname(File::Temp.temp_name))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
test "temp path basic functionality" do
|
92
|
+
@fh = File::Temp.new
|
93
|
+
assert_respond_to(@fh, :path)
|
94
|
+
end
|
95
|
+
|
96
|
+
test "temp path is nil if delete option is true" do
|
97
|
+
@fh = File::Temp.new
|
98
|
+
assert_nil(@fh.path)
|
99
|
+
end
|
100
|
+
|
101
|
+
test "temp path is not nil if delete option is false" do
|
102
|
+
@fh = File::Temp.new(false)
|
103
|
+
assert_not_nil(@fh.path)
|
104
|
+
end
|
105
|
+
|
106
|
+
test "ffi functions are private" do
|
107
|
+
methods = File::Temp.methods(false).map{ |e| e.to_s }
|
108
|
+
assert_false(methods.include?('_fileno'))
|
109
|
+
assert_false(methods.include?('mkstemp'))
|
110
|
+
assert_false(methods.include?('_umask'))
|
111
|
+
assert_false(methods.include?('fclose'))
|
112
|
+
assert_false(methods.include?('strerror'))
|
113
|
+
assert_false(methods.include?('tmpnam'))
|
114
|
+
assert_false(methods.include?('CloseHandle'))
|
115
|
+
assert_false(methods.include?('CreateFileA'))
|
116
|
+
assert_false(methods.include?('DeleteFileA'))
|
117
|
+
assert_false(methods.include?('GetTempPathA'))
|
118
|
+
assert_false(methods.include?('GetTempFileNameA'))
|
119
|
+
end
|
120
|
+
|
121
|
+
def teardown
|
122
|
+
@dir = nil
|
123
|
+
@template = nil
|
124
|
+
@fh.close if @fh && !@fh.closed?
|
125
|
+
@fh = nil
|
126
|
+
|
127
|
+
Dir["temp_*"].each{ |f| File.delete(f) }
|
128
|
+
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
129
|
+
|
130
|
+
Dir.chdir(File::Temp::TMPDIR) do
|
131
|
+
Dir["temp_*"].each{ |f| File.delete(f) }
|
132
|
+
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|