file-temp 1.1.5 → 1.2.0
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.
- data/CHANGES +50 -43
- data/MANIFEST +6 -6
- data/README +56 -61
- data/Rakefile +61 -61
- data/file-temp.gemspec +26 -26
- data/lib/file/temp.rb +254 -225
- data/test/test_file_temp.rb +120 -108
- metadata +40 -66
data/CHANGES
CHANGED
@@ -1,43 +1,50 @@
|
|
1
|
-
= 1.
|
2
|
-
*
|
3
|
-
|
4
|
-
*
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
*
|
12
|
-
|
13
|
-
= 1.1.
|
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
|
-
*
|
1
|
+
= 1.2.0 - 10-Apr-2012
|
2
|
+
* Removed the old FileTemp alias for File::Temp. It was deprecated and
|
3
|
+
has now been officially removed.
|
4
|
+
* Some refactoring of the custom internal Windows functions.
|
5
|
+
* Nicer error handling if certain FFI functions fail.
|
6
|
+
* Made the FFI functions private.
|
7
|
+
|
8
|
+
= 1.1.5 - 17-Jul-2011
|
9
|
+
* Now stores file path information if the file is retained on the filesystem.
|
10
|
+
Thanks go to joerixaop for the patch.
|
11
|
+
* The TMPDIR fallback determination on Windows is no longer hard coded.
|
12
|
+
|
13
|
+
= 1.1.4 - 16-Sep-2010
|
14
|
+
* The File::Temp.temp_name method has been altered on Unix systems. It
|
15
|
+
no longer prefixes TMPDIR to the name since it was redundant and could
|
16
|
+
generate a bogus path.
|
17
|
+
* Set the license to Artistic 2.0.
|
18
|
+
* Set the test task as the default Rake task.
|
19
|
+
|
20
|
+
= 1.1.3 - 14-Sep-2010
|
21
|
+
* Fixed potential libc linker failure.
|
22
|
+
|
23
|
+
= 1.1.2 - 28-Apr-2010
|
24
|
+
* Explicitly link against libc for Unix versions.
|
25
|
+
* Refactored the Rakefile. An old install task was removed and the gem
|
26
|
+
related tasks were placed under the 'gem' namespace.
|
27
|
+
|
28
|
+
= 1.1.1 - 24-Oct-2009
|
29
|
+
* Removed the 'use' library as a dependency.
|
30
|
+
|
31
|
+
= 1.1.0 - 21-Oct-2009
|
32
|
+
* Now pure Ruby, using FFI.
|
33
|
+
* Fixed RF Bug #26757 - FILE pointer leak. Thanks go to Eric Wong for the spot.
|
34
|
+
* Renamed and refactored the test file slightly.
|
35
|
+
* Updated the gemspec.
|
36
|
+
|
37
|
+
= 1.0.0 - 12-Apr-2008
|
38
|
+
* Added security via umask().
|
39
|
+
* Version bump to 1.0.0.
|
40
|
+
|
41
|
+
= 0.1.2 - 6-Jun-2007
|
42
|
+
* Gemspec fix (forgot the temp.h file - oops).
|
43
|
+
* Added an extra test.
|
44
|
+
|
45
|
+
= 0.1.1 - 2-Jun-2007
|
46
|
+
* Core code and test case now work properly on MS Windows.
|
47
|
+
* Now uses MS VC++ 8 functions when available (tmpfile_s, _sopen_s).
|
48
|
+
|
49
|
+
= 0.1.0 - 1-Jun-2007
|
50
|
+
* Initial release.
|
data/MANIFEST
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
* CHANGES
|
2
|
-
* MANIFEST
|
3
|
-
* README
|
4
|
-
* Rakefile
|
5
|
-
* file-temp.gemspec
|
6
|
-
* lib/file/temp.rb
|
1
|
+
* CHANGES
|
2
|
+
* MANIFEST
|
3
|
+
* README
|
4
|
+
* Rakefile
|
5
|
+
* file-temp.gemspec
|
6
|
+
* lib/file/temp.rb
|
7
7
|
* test/test_file_temp.rb
|
data/README
CHANGED
@@ -1,61 +1,56 @@
|
|
1
|
-
== Description
|
2
|
-
The file-temp library is an alternate way to handle tempfile generation.
|
3
|
-
|
4
|
-
== Requirements
|
5
|
-
ffi 0.5.0 or later
|
6
|
-
|
7
|
-
==
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
fh
|
15
|
-
fh.
|
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
|
-
== Author
|
58
|
-
Daniel J. Berger
|
59
|
-
|
60
|
-
== See also
|
61
|
-
tmpfile(), mkstemp(), tmpnam()
|
1
|
+
== Description
|
2
|
+
The file-temp library is an alternate way to handle tempfile generation.
|
3
|
+
|
4
|
+
== Requirements
|
5
|
+
ffi 0.5.0 or later
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
gem install file-temp
|
9
|
+
|
10
|
+
== Synopsis
|
11
|
+
require 'file/temp'
|
12
|
+
|
13
|
+
fh = File::Temp.new
|
14
|
+
fh.puts "hello"
|
15
|
+
fh.close # => Tempfile automatically deleted
|
16
|
+
|
17
|
+
fh = File::Temp.new(false)
|
18
|
+
fh.puts "world"
|
19
|
+
fh.close # => Tempfile still on your filesystem
|
20
|
+
|
21
|
+
== Motivation
|
22
|
+
Ruby's tempfile.rb is overwrought and susceptible to race conditions. This
|
23
|
+
This library uses your system's native tmpfile() or mkstemp() functions
|
24
|
+
instead of trying to handle race conditions manually via pure Ruby.
|
25
|
+
|
26
|
+
This library is also more secure because it restricts file permission via
|
27
|
+
umask() for files created with mkstemp().
|
28
|
+
|
29
|
+
Finally, this library subclasses the File class. This means you get almost
|
30
|
+
exactly the same interface as the File class. The only difference is the
|
31
|
+
constructor.
|
32
|
+
|
33
|
+
== JRuby
|
34
|
+
I'm afraid this library will not work with JRuby due to limitations
|
35
|
+
of JRuby itself.
|
36
|
+
|
37
|
+
== MS Windows
|
38
|
+
You may need to use the mingw build in order to use this library.
|
39
|
+
|
40
|
+
== License
|
41
|
+
Artistic 2.0
|
42
|
+
|
43
|
+
== Copyright
|
44
|
+
(C) 2007-2012 Daniel J. Berger
|
45
|
+
All Rights Reserved
|
46
|
+
|
47
|
+
== Warranty
|
48
|
+
This library is provided "as is" and without any express or
|
49
|
+
implied warranties, including, without limitation, the implied
|
50
|
+
warranties of merchantability and fitness for a particular purpose.
|
51
|
+
|
52
|
+
== Author
|
53
|
+
Daniel J. Berger
|
54
|
+
|
55
|
+
== See also
|
56
|
+
tmpfile(), mkstemp(), tmpnam()
|
data/Rakefile
CHANGED
@@ -1,61 +1,61 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/clean'
|
3
|
-
require 'rake/testtask'
|
4
|
-
|
5
|
-
CLEAN.include('**/*.tar', '**/*.zip', '**/*.gz', '**/*.bz2')
|
6
|
-
CLEAN.include('**/*.rbc', '**/*.gem')
|
7
|
-
|
8
|
-
namespace 'gem' do
|
9
|
-
desc 'Create the file-temp gem'
|
10
|
-
task :create => [:clean] do
|
11
|
-
spec = eval(IO.read('file-temp.gemspec'))
|
12
|
-
Gem::Builder.new(spec).build
|
13
|
-
end
|
14
|
-
|
15
|
-
desc 'Install the file-temp gem'
|
16
|
-
task :install => [:create] do
|
17
|
-
file = Dir["*.gem"].first
|
18
|
-
sh "gem install #{file}"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Export the contents of the library to an archive. Note that this requires
|
23
|
-
# presence of the .gitattributes file in order to prevent the .git contents
|
24
|
-
# from being included.
|
25
|
-
#
|
26
|
-
# It also appears that I must add a trailing slash to the prefix manually.
|
27
|
-
# As of git 1.6.4.3 it does not automaticaly add it, despite what the docs
|
28
|
-
# say.
|
29
|
-
#
|
30
|
-
namespace 'export' do
|
31
|
-
spec = eval(IO.read('file-temp.gemspec'))
|
32
|
-
file = 'file-temp-' + spec.version.to_s
|
33
|
-
pref = file + '/' # Git does not add the trailing slash, despite what the docs say.
|
34
|
-
|
35
|
-
desc 'Export to a .tar.gz file'
|
36
|
-
task :gzip => [:clean] do
|
37
|
-
file += '.tar'
|
38
|
-
sh "git archive --prefix #{pref} --output #{file} master"
|
39
|
-
sh "gzip #{file}"
|
40
|
-
end
|
41
|
-
|
42
|
-
desc 'Export to a .tar.bz2 file'
|
43
|
-
task :bzip2 => [:clean] do
|
44
|
-
file += '.tar'
|
45
|
-
sh "git archive --prefix #{pref} --output #{file} master"
|
46
|
-
sh "bzip2 -f #{file}"
|
47
|
-
end
|
48
|
-
|
49
|
-
desc 'Export to a .zip file'
|
50
|
-
task :zip => [:clean] do
|
51
|
-
file += '.zip'
|
52
|
-
sh "git archive --prefix #{pref} --output #{file} --format zip master"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
Rake::TestTask.new do |t|
|
57
|
-
t.verbose = true
|
58
|
-
t.warning = true
|
59
|
-
end
|
60
|
-
|
61
|
-
task :default => :test
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
CLEAN.include('**/*.tar', '**/*.zip', '**/*.gz', '**/*.bz2')
|
6
|
+
CLEAN.include('**/*.rbc', '**/*.gem')
|
7
|
+
|
8
|
+
namespace 'gem' do
|
9
|
+
desc 'Create the file-temp gem'
|
10
|
+
task :create => [:clean] do
|
11
|
+
spec = eval(IO.read('file-temp.gemspec'))
|
12
|
+
Gem::Builder.new(spec).build
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Install the file-temp gem'
|
16
|
+
task :install => [:create] do
|
17
|
+
file = Dir["*.gem"].first
|
18
|
+
sh "gem install #{file}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Export the contents of the library to an archive. Note that this requires
|
23
|
+
# presence of the .gitattributes file in order to prevent the .git contents
|
24
|
+
# from being included.
|
25
|
+
#
|
26
|
+
# It also appears that I must add a trailing slash to the prefix manually.
|
27
|
+
# As of git 1.6.4.3 it does not automaticaly add it, despite what the docs
|
28
|
+
# say.
|
29
|
+
#
|
30
|
+
namespace 'export' do
|
31
|
+
spec = eval(IO.read('file-temp.gemspec'))
|
32
|
+
file = 'file-temp-' + spec.version.to_s
|
33
|
+
pref = file + '/' # Git does not add the trailing slash, despite what the docs say.
|
34
|
+
|
35
|
+
desc 'Export to a .tar.gz file'
|
36
|
+
task :gzip => [:clean] do
|
37
|
+
file += '.tar'
|
38
|
+
sh "git archive --prefix #{pref} --output #{file} master"
|
39
|
+
sh "gzip #{file}"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Export to a .tar.bz2 file'
|
43
|
+
task :bzip2 => [:clean] do
|
44
|
+
file += '.tar'
|
45
|
+
sh "git archive --prefix #{pref} --output #{file} master"
|
46
|
+
sh "bzip2 -f #{file}"
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'Export to a .zip file'
|
50
|
+
task :zip => [:clean] do
|
51
|
+
file += '.zip'
|
52
|
+
sh "git archive --prefix #{pref} --output #{file} --format zip master"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Rake::TestTask.new do |t|
|
57
|
+
t.verbose = true
|
58
|
+
t.warning = true
|
59
|
+
end
|
60
|
+
|
61
|
+
task :default => :test
|
data/file-temp.gemspec
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
Gem::Specification.new do |spec|
|
4
|
-
spec.name = 'file-temp'
|
5
|
-
spec.version = '1.
|
6
|
-
spec.author = 'Daniel J. Berger'
|
7
|
-
spec.license = 'Artistic 2.0'
|
8
|
-
spec.email = 'djberg96@gmail.com'
|
9
|
-
spec.homepage = 'http://www.rubyforge.org/projects/shards'
|
10
|
-
spec.summary = 'An alternative way to generate temp files'
|
11
|
-
spec.test_file = 'test/test_file_temp.rb'
|
12
|
-
spec.files = Dir['**/*'].delete_if{ |item| item.include?('git') }
|
13
|
-
|
14
|
-
spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
|
15
|
-
spec.rubyforge_project = 'shards'
|
16
|
-
spec.required_ruby_version = '>= 1.8.6'
|
17
|
-
|
18
|
-
spec.add_dependency('ffi', '>= 0.
|
19
|
-
spec.add_development_dependency('test-unit', '>= 2.
|
20
|
-
|
21
|
-
spec.description = <<-EOF
|
22
|
-
The file-temp library provides an alternative approach to generating
|
23
|
-
temporary files. Features included improved security, a superior
|
24
|
-
interface, and better support for MS Windows.
|
25
|
-
EOF
|
26
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'file-temp'
|
5
|
+
spec.version = '1.2.0'
|
6
|
+
spec.author = 'Daniel J. Berger'
|
7
|
+
spec.license = 'Artistic 2.0'
|
8
|
+
spec.email = 'djberg96@gmail.com'
|
9
|
+
spec.homepage = 'http://www.rubyforge.org/projects/shards'
|
10
|
+
spec.summary = 'An alternative way to generate temp files'
|
11
|
+
spec.test_file = 'test/test_file_temp.rb'
|
12
|
+
spec.files = Dir['**/*'].delete_if{ |item| item.include?('git') }
|
13
|
+
|
14
|
+
spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
|
15
|
+
spec.rubyforge_project = 'shards'
|
16
|
+
spec.required_ruby_version = '>= 1.8.6'
|
17
|
+
|
18
|
+
spec.add_dependency('ffi', '>= 1.0.0')
|
19
|
+
spec.add_development_dependency('test-unit', '>= 2.4.0')
|
20
|
+
|
21
|
+
spec.description = <<-EOF
|
22
|
+
The file-temp library provides an alternative approach to generating
|
23
|
+
temporary files. Features included improved security, a superior
|
24
|
+
interface, and better support for MS Windows.
|
25
|
+
EOF
|
26
|
+
end
|
data/lib/file/temp.rb
CHANGED
@@ -1,225 +1,254 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
class File::Temp < File
|
5
|
-
extend FFI::Library
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
attach_function
|
18
|
-
attach_function
|
19
|
-
attach_function
|
20
|
-
attach_function
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
attach_function
|
25
|
-
attach_function
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
attach_function
|
30
|
-
attach_function
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
attach_function
|
52
|
-
attach_function
|
53
|
-
attach_function
|
54
|
-
attach_function
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
#
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
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 :_mktemp_s, [:pointer, :size_t], :int
|
18
|
+
attach_function :_open, [:string, :int, :int], :int
|
19
|
+
attach_function :_open_osfhandle, [:long, :int], :int
|
20
|
+
attach_function :tmpnam, [:string], :string
|
21
|
+
|
22
|
+
ffi_lib :kernel32
|
23
|
+
|
24
|
+
attach_function :CloseHandle, [:long], :bool
|
25
|
+
attach_function :CreateFileA, [:string, :ulong, :ulong, :pointer, :ulong, :ulong, :ulong], :long
|
26
|
+
attach_function :DeleteFileA, [:string], :bool
|
27
|
+
attach_function :FormatMessageA, [:long, :long, :long, :long, :pointer, :long, :pointer], :long
|
28
|
+
attach_function :GetLastError, [], :int
|
29
|
+
attach_function :GetTempPathA, [:long, :pointer], :long
|
30
|
+
attach_function :GetTempFileNameA, [:string, :string, :uint, :pointer], :uint
|
31
|
+
|
32
|
+
private_class_method :_close, :_fdopen, :_mktemp_s, :_open, :_open_osfhandle
|
33
|
+
private_class_method :CloseHandle, :CreateFileA, :DeleteFileA, :FormatMessageA
|
34
|
+
private_class_method :GetLastError, :GetTempPathA, :GetTempFileNameA
|
35
|
+
|
36
|
+
S_IWRITE = 128
|
37
|
+
S_IREAD = 256
|
38
|
+
BINARY = 0x8000
|
39
|
+
SHORT_LIVED = 0x1000
|
40
|
+
GENERIC_READ = 0x80000000
|
41
|
+
GENERIC_WRITE = 0x40000000
|
42
|
+
CREATE_ALWAYS = 2
|
43
|
+
|
44
|
+
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
|
45
|
+
FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000
|
46
|
+
|
47
|
+
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
48
|
+
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
|
49
|
+
INVALID_HANDLE_VALUE = -1
|
50
|
+
else
|
51
|
+
attach_function :fclose, [:pointer], :int
|
52
|
+
attach_function :_fileno, :fileno, [:pointer], :int
|
53
|
+
attach_function :mkstemp, [:string], :int
|
54
|
+
attach_function :strerror, [:int], :string
|
55
|
+
attach_function :tmpfile, [], :pointer
|
56
|
+
attach_function :tmpnam, [:string], :string
|
57
|
+
|
58
|
+
private_class_method :mkstemp, :strerror, :tmpfile
|
59
|
+
end
|
60
|
+
|
61
|
+
private_class_method :fclose, :_fileno, :tmpnam
|
62
|
+
|
63
|
+
public
|
64
|
+
|
65
|
+
# :startdoc:
|
66
|
+
|
67
|
+
# The version of the file-temp library.
|
68
|
+
VERSION = '1.2.0'
|
69
|
+
|
70
|
+
# The temporary directory used on MS Windows or Unix.
|
71
|
+
if File::ALT_SEPARATOR
|
72
|
+
TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['USERPROFILE'] || Dir.tmpdir
|
73
|
+
else
|
74
|
+
TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['TMPDIR'] || Dir.tmpdir
|
75
|
+
end
|
76
|
+
|
77
|
+
# The name of the file. This is only retained if the first argument to the
|
78
|
+
# constructor is false.
|
79
|
+
attr_reader :path
|
80
|
+
|
81
|
+
# Creates a new, anonymous, temporary file in your File::Temp::TMPDIR
|
82
|
+
# directory
|
83
|
+
#
|
84
|
+
# If the +delete+ option is set to true (the default) then the temporary file
|
85
|
+
# will be deleted automatically as soon as all references to it are closed.
|
86
|
+
# Otherwise, the file will live on in your File::Temp::TMPDIR path.
|
87
|
+
#
|
88
|
+
# If the +delete+ option is set to false, then the file is not deleted. In
|
89
|
+
# addition, you can supply a string +template+ that the system replaces with
|
90
|
+
# a unique filename. This template should end with 3 to 6 'X' characters.
|
91
|
+
# The default template is 'rb_file_temp_XXXXXX'. In this case the temporary
|
92
|
+
# file lives in the directory where it was created.
|
93
|
+
#
|
94
|
+
# The +template+ argument is ignored if the +delete+ argument is true.
|
95
|
+
#
|
96
|
+
# Example:
|
97
|
+
#
|
98
|
+
# fh = File::Temp.new(true, 'rb_file_temp_XXXXXX') => file
|
99
|
+
# fh.puts 'hello world'
|
100
|
+
# fh.close
|
101
|
+
#
|
102
|
+
def initialize(delete = true, template = 'rb_file_temp_XXXXXX')
|
103
|
+
@fptr = nil
|
104
|
+
|
105
|
+
if delete
|
106
|
+
@fptr = tmpfile()
|
107
|
+
fd = _fileno(@fptr)
|
108
|
+
else
|
109
|
+
begin
|
110
|
+
omask = File.umask(077)
|
111
|
+
|
112
|
+
if File::ALT_SEPARATOR
|
113
|
+
ptr = FFI::MemoryPointer.from_string(template.dup)
|
114
|
+
|
115
|
+
if _mktemp_s(ptr, ptr.size) != 0
|
116
|
+
raise SystemCallError, '_mktemp_s function failed: ' + get_error
|
117
|
+
end
|
118
|
+
|
119
|
+
template = ptr.read_string
|
120
|
+
end
|
121
|
+
|
122
|
+
@path = File.join(TMPDIR, template)
|
123
|
+
fd = mkstemp(@path)
|
124
|
+
|
125
|
+
if fd < 0
|
126
|
+
raise SystemCallError, 'mkstemp function failed: ' + get_error
|
127
|
+
end
|
128
|
+
ensure
|
129
|
+
File.umask(omask)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
super(fd, 'wb+')
|
134
|
+
end
|
135
|
+
|
136
|
+
# The close method was overridden to ensure the internal file pointer we
|
137
|
+
# created in the constructor is closed. It is otherwise identical to the
|
138
|
+
# File#close method.
|
139
|
+
#
|
140
|
+
def close
|
141
|
+
super
|
142
|
+
fclose(@fptr) if @fptr
|
143
|
+
end
|
144
|
+
|
145
|
+
# Generates a unique file name.
|
146
|
+
#
|
147
|
+
# Note that a file is not actually generated on the filesystem.
|
148
|
+
#
|
149
|
+
def self.temp_name
|
150
|
+
if File::ALT_SEPARATOR
|
151
|
+
TMPDIR + tmpnam(nil) << '.tmp'
|
152
|
+
else
|
153
|
+
tmpnam(nil) << '.tmp'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def get_error
|
160
|
+
if File::ALT_SEPARATOR
|
161
|
+
errno = GetLastError()
|
162
|
+
buffer = FFI::MemoryPointer.new(:char, 512)
|
163
|
+
flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY
|
164
|
+
|
165
|
+
FormatMessageA(flags, 0, errno, 0, buffer, buffer.size, nil)
|
166
|
+
|
167
|
+
buffer.read_string
|
168
|
+
else
|
169
|
+
strerror(FFI.errno)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
if File::ALT_SEPARATOR
|
174
|
+
|
175
|
+
# Simple wrapper around the GetTempPath function.
|
176
|
+
#
|
177
|
+
def get_temp_path
|
178
|
+
buf = FFI::MemoryPointer.new(:char, 1024)
|
179
|
+
|
180
|
+
if GetTempPathA(buf.size, buf) == 0
|
181
|
+
raise SystemCallError, 'GetTempPathA function failed: ' + get_error
|
182
|
+
end
|
183
|
+
|
184
|
+
buf.read_string.chop # remove trailing slash
|
185
|
+
end
|
186
|
+
|
187
|
+
# The version of tmpfile() implemented by Microsoft is unacceptable.
|
188
|
+
# It attempts to write to C:\ (root) instead of a temporary directory.
|
189
|
+
# This is not only bad behavior, it won't work on Windows 7 and later
|
190
|
+
# without admin rights due to security restrictions.
|
191
|
+
#
|
192
|
+
# This is a custom implementation based on some code from the Cairo
|
193
|
+
# project.
|
194
|
+
#
|
195
|
+
def tmpfile
|
196
|
+
file_name = get_temp_path()
|
197
|
+
buf = FFI::MemoryPointer.new(:char, 1024)
|
198
|
+
|
199
|
+
if GetTempFileNameA(file_name, 'rb_', 0, buf) == 0
|
200
|
+
raise SystemCallError, 'GetTempFileNameA function failed: ' + get_error
|
201
|
+
end
|
202
|
+
|
203
|
+
file_name = buf.read_string
|
204
|
+
|
205
|
+
handle = CreateFileA(
|
206
|
+
file_name,
|
207
|
+
GENERIC_READ | GENERIC_WRITE,
|
208
|
+
0,
|
209
|
+
nil,
|
210
|
+
CREATE_ALWAYS,
|
211
|
+
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
|
212
|
+
0
|
213
|
+
)
|
214
|
+
|
215
|
+
if handle == INVALID_HANDLE_VALUE
|
216
|
+
DeleteFileA(file_name)
|
217
|
+
raise SystemCallError, 'CreateFileA function failed: ' + get_error
|
218
|
+
end
|
219
|
+
|
220
|
+
fd = _open_osfhandle(handle, 0)
|
221
|
+
|
222
|
+
if fd < 0
|
223
|
+
CloseHandle(handle)
|
224
|
+
raise SystemCallError, '_open_osfhandle function failed: ' + get_error
|
225
|
+
end
|
226
|
+
|
227
|
+
fp = _fdopen(fd, 'w+b')
|
228
|
+
|
229
|
+
if fp.nil?
|
230
|
+
_close(fd)
|
231
|
+
CloseHandle(handle)
|
232
|
+
raise SystemCallError, 'fdopen function failed: ' + get_error
|
233
|
+
end
|
234
|
+
|
235
|
+
fp
|
236
|
+
end
|
237
|
+
|
238
|
+
# The MS C runtime does not define a mkstemp() function, so we've
|
239
|
+
# created one here.
|
240
|
+
#
|
241
|
+
def mkstemp(template)
|
242
|
+
flags = RDWR | BINARY | CREAT | EXCL | SHORT_LIVED
|
243
|
+
pmode = S_IREAD | S_IWRITE
|
244
|
+
|
245
|
+
fd = _open(template, flags, pmode)
|
246
|
+
|
247
|
+
if fd < 0
|
248
|
+
raise SystemCallError, '_open function failed: ' + get_error
|
249
|
+
end
|
250
|
+
|
251
|
+
fd
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
data/test/test_file_temp.rb
CHANGED
@@ -1,108 +1,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
|
-
|
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
|
-
|
107
|
-
|
108
|
-
|
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
|
+
def test_file_temp_version
|
24
|
+
assert_equal('1.2.0', File::Temp::VERSION)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_file_temp_threaded
|
28
|
+
threads = []
|
29
|
+
assert_nothing_raised{ 100.times{ threads << Thread.new{ File::Temp.new }}}
|
30
|
+
assert_nothing_raised{ threads.join }
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_file_temp_tmpdir
|
34
|
+
assert_not_nil(File::Temp::TMPDIR)
|
35
|
+
assert_kind_of(String, File::Temp::TMPDIR)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_file_temp_auto_delete
|
39
|
+
assert_nothing_raised{ @fh = File::Temp.new }
|
40
|
+
assert_nothing_raised{ @fh.print "hello" }
|
41
|
+
assert_nothing_raised{ @fh.close }
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_file_temp_no_delete
|
45
|
+
assert_nothing_raised{ @fh = File::Temp.new(false) }
|
46
|
+
assert_nothing_raised{ @fh.print "hello" }
|
47
|
+
assert_nothing_raised{ @fh.close }
|
48
|
+
assert_true(Dir["#{@dir}/rb_file_temp*"].length == 1)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_file_temp_no_delete_with_template
|
52
|
+
assert_nothing_raised{ File::Temp.new(false, 'temp_foo_XXXXXX').close }
|
53
|
+
assert_true(Dir["#{@dir}/temp_foo*"].length >= 1)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_file_temp_no_delete_with_block
|
57
|
+
assert_nothing_raised{ File::Temp.open(false, 'temp_foo_XXXXXX'){ |fh| fh.puts "hello" } }
|
58
|
+
assert_true(Dir["#{@dir}/temp_foo*"].length >= 1)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_file_temp_expected_errors
|
62
|
+
assert_raise(TypeError, ArgumentError){ @fh = File::Temp.new(false, 1) }
|
63
|
+
assert_raise(ArgumentError){ @fh = File::Temp.new(true, 'temp_bar_XXXXX', 1) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_file_temp_name_basic_functionality
|
67
|
+
assert_respond_to(File::Temp, :temp_name)
|
68
|
+
assert_nothing_raised{ File::Temp.temp_name }
|
69
|
+
assert_kind_of(String, File::Temp.temp_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_file_temp_name
|
73
|
+
assert_equal('.tmp', File.extname(File::Temp.temp_name))
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_file_temp_path_basic_functionality
|
77
|
+
@fh = File::Temp.new
|
78
|
+
assert_respond_to(@fh, :path)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_file_temp_path_is_nil_if_delete_option_is_true
|
82
|
+
@fh = File::Temp.new
|
83
|
+
assert_nil(@fh.path)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_file_temp_path_is_not_nil_if_delete_option_is_false
|
87
|
+
@fh = File::Temp.new(false)
|
88
|
+
assert_not_nil(@fh.path)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_ffi_functions_are_private
|
92
|
+
methods = File::Temp.methods(false).map{ |e| e.to_s }
|
93
|
+
assert_false(methods.include?('_fileno'))
|
94
|
+
assert_false(methods.include?('mkstemp'))
|
95
|
+
assert_false(methods.include?('_umask'))
|
96
|
+
assert_false(methods.include?('fclose'))
|
97
|
+
assert_false(methods.include?('strerror'))
|
98
|
+
assert_false(methods.include?('tmpnam'))
|
99
|
+
assert_false(methods.include?('CloseHandle'))
|
100
|
+
assert_false(methods.include?('CreateFileA'))
|
101
|
+
assert_false(methods.include?('DeleteFileA'))
|
102
|
+
assert_false(methods.include?('GetTempPathA'))
|
103
|
+
assert_false(methods.include?('GetTempFileNameA'))
|
104
|
+
end
|
105
|
+
|
106
|
+
def teardown
|
107
|
+
@dir = nil
|
108
|
+
@template = nil
|
109
|
+
@fh.close if @fh && !@fh.closed?
|
110
|
+
@fh = nil
|
111
|
+
|
112
|
+
Dir["temp_*"].each{ |f| File.delete(f) }
|
113
|
+
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
114
|
+
|
115
|
+
Dir.chdir(File::Temp::TMPDIR) do
|
116
|
+
Dir["temp_*"].each{ |f| File.delete(f) }
|
117
|
+
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
metadata
CHANGED
@@ -1,65 +1,49 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: file-temp
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 1
|
9
|
-
- 5
|
10
|
-
version: 1.1.5
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Daniel J. Berger
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-04-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: ffi
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &22367490 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
- 5
|
32
|
-
- 0
|
33
|
-
version: 0.5.0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.0.0
|
34
22
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: test-unit
|
38
23
|
prerelease: false
|
39
|
-
|
24
|
+
version_requirements: *22367490
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: test-unit
|
27
|
+
requirement: &22367140 !ruby/object:Gem::Requirement
|
40
28
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 2
|
47
|
-
- 2
|
48
|
-
- 0
|
49
|
-
version: 2.2.0
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.4.0
|
50
33
|
type: :development
|
51
|
-
|
52
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *22367140
|
36
|
+
description: ! " The file-temp library provides an alternative approach to generating\n
|
37
|
+
\ temporary files. Features included improved security, a superior\n interface,
|
38
|
+
and better support for MS Windows.\n"
|
53
39
|
email: djberg96@gmail.com
|
54
40
|
executables: []
|
55
|
-
|
56
41
|
extensions: []
|
57
|
-
|
58
|
-
extra_rdoc_files:
|
42
|
+
extra_rdoc_files:
|
59
43
|
- CHANGES
|
60
44
|
- README
|
61
45
|
- MANIFEST
|
62
|
-
files:
|
46
|
+
files:
|
63
47
|
- CHANGES
|
64
48
|
- file-temp.gemspec
|
65
49
|
- lib/file/temp.rb
|
@@ -68,39 +52,29 @@ files:
|
|
68
52
|
- README
|
69
53
|
- test/test_file_temp.rb
|
70
54
|
homepage: http://www.rubyforge.org/projects/shards
|
71
|
-
licenses:
|
55
|
+
licenses:
|
72
56
|
- Artistic 2.0
|
73
57
|
post_install_message:
|
74
58
|
rdoc_options: []
|
75
|
-
|
76
|
-
require_paths:
|
59
|
+
require_paths:
|
77
60
|
- lib
|
78
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
62
|
none: false
|
80
|
-
requirements:
|
81
|
-
- -
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
hash: 59
|
84
|
-
segments:
|
85
|
-
- 1
|
86
|
-
- 8
|
87
|
-
- 6
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
88
66
|
version: 1.8.6
|
89
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
68
|
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
segments:
|
96
|
-
- 0
|
97
|
-
version: "0"
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
98
73
|
requirements: []
|
99
|
-
|
100
74
|
rubyforge_project: shards
|
101
|
-
rubygems_version: 1.8.
|
75
|
+
rubygems_version: 1.8.11
|
102
76
|
signing_key:
|
103
77
|
specification_version: 3
|
104
78
|
summary: An alternative way to generate temp files
|
105
|
-
test_files:
|
79
|
+
test_files:
|
106
80
|
- test/test_file_temp.rb
|