file-temp 1.0.0 → 1.1.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 +7 -1
- data/MANIFEST +2 -3
- data/README +28 -23
- data/Rakefile +16 -40
- data/file-temp.gemspec +27 -0
- data/lib/file/temp.rb +211 -0
- data/test/test_file_temp.rb +91 -0
- metadata +46 -15
- data/ext/extconf.rb +0 -13
- data/ext/temp.c +0 -120
- data/test/tc_file_temp.rb +0 -64
data/CHANGES
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
= 1.
|
1
|
+
= 1.1.0 - 21-Oct-2009
|
2
|
+
* Now pure Ruby, using FFI.
|
3
|
+
* Fixed RF Bug #26757 - FILE pointer leak. Thanks go to Eric Wong for the spot.
|
4
|
+
* Renamed and refactored the test file slightly.
|
5
|
+
* Updated the gemspec.
|
6
|
+
|
7
|
+
= 1.0.0 - 12-Apr-2008
|
2
8
|
* Added security via umask().
|
3
9
|
* Version bump to 1.0.0.
|
4
10
|
|
data/MANIFEST
CHANGED
data/README
CHANGED
@@ -1,27 +1,29 @@
|
|
1
|
-
|
1
|
+
== Description
|
2
2
|
The file-temp library is an alternate way to handle tempfile generation.
|
3
3
|
|
4
|
-
|
4
|
+
== Requirements
|
5
|
+
ffi 0.5.0 or later
|
6
|
+
|
7
|
+
== Synopsis
|
5
8
|
require 'file/temp'
|
6
9
|
|
7
|
-
fh =
|
10
|
+
fh = File::Temp.new
|
8
11
|
fh.puts "hello"
|
9
12
|
fh.close # => Tempfile automatically deleted
|
10
13
|
|
11
|
-
fh =
|
14
|
+
fh = File::Temp.new(false)
|
12
15
|
fh.puts "world"
|
13
16
|
fh.close # => Tempfile still on your filesystem
|
14
17
|
|
15
|
-
|
16
|
-
|
18
|
+
== Installation
|
19
|
+
=== Rubygems
|
20
|
+
gem install file-temp
|
21
|
+
|
22
|
+
=== Standard Installation
|
17
23
|
rake test (optional)
|
18
24
|
rake install
|
19
25
|
|
20
|
-
==
|
21
|
-
rake test (optional)
|
22
|
-
rake gem_install
|
23
|
-
|
24
|
-
= Motivation
|
26
|
+
== Motivation
|
25
27
|
Ruby's tempfile.rb is overwrought and susceptible to race conditions. This
|
26
28
|
This library uses your system's native tmpfile() or mkstemp() functions
|
27
29
|
instead of trying to handle race conditions manually via pure Ruby.
|
@@ -29,31 +31,34 @@
|
|
29
31
|
This library is also more secure because it restricts file permission via
|
30
32
|
umask() for files created with mkstemp().
|
31
33
|
|
32
|
-
|
34
|
+
== Other libraries
|
33
35
|
I am aware of Cian Synnott's ruby-stemp project. However, I don't like the
|
34
36
|
interface, it's GNU-centric (which causes portability issues), and Cian
|
35
37
|
has disabled all the trackers and mailing lists on the RubyForge project
|
36
38
|
site, as well as online SCM access. So, if he doesn't want feedback, I'm
|
37
39
|
not going to waste time with it.
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
+
== JRuby
|
42
|
+
As of JRuby 1.3.1 this library will not work with JRuby because it does
|
43
|
+
not support low level systems programming.
|
44
|
+
|
45
|
+
== MS Windows
|
46
|
+
You may need to use the mingw build in order to use this library.
|
41
47
|
|
42
|
-
|
43
|
-
|
48
|
+
== License
|
49
|
+
Artistic 2.0
|
44
50
|
|
45
|
-
|
46
|
-
(C) 2007-
|
51
|
+
== Copyright
|
52
|
+
(C) 2007-2009 Daniel J. Berger
|
47
53
|
All Rights Reserved
|
48
54
|
|
49
|
-
|
50
|
-
This
|
55
|
+
== Warranty
|
56
|
+
This library is provided "as is" and without any express or
|
51
57
|
implied warranties, including, without limitation, the implied
|
52
58
|
warranties of merchantability and fitness for a particular purpose.
|
53
59
|
|
54
|
-
|
60
|
+
== Author
|
55
61
|
Daniel J. Berger
|
56
|
-
djberg96 at gmail dot com
|
57
62
|
|
58
|
-
|
63
|
+
== See also
|
59
64
|
tmpfile(), mkstemp(), tmpnam()
|
data/Rakefile
CHANGED
@@ -1,51 +1,27 @@
|
|
1
1
|
require 'rake'
|
2
|
-
require 'rake/clean'
|
3
2
|
require 'rake/testtask'
|
3
|
+
require 'rbconfig'
|
4
4
|
|
5
|
-
desc
|
6
|
-
task :
|
7
|
-
|
8
|
-
Dir.
|
9
|
-
|
10
|
-
|
11
|
-
obj_file = 'temp.obj'
|
12
|
-
if File.exists?(build_file) || File.exists?(obj_file)
|
13
|
-
sh "#{make} distclean"
|
14
|
-
end
|
15
|
-
File.delete("temp.so.manifest") if File.exists?("temp.so.manifest")
|
16
|
-
end
|
5
|
+
desc 'Install the file-temp library (non-gem)'
|
6
|
+
task :install do
|
7
|
+
dir = File.join(CONFIG['sitelibdir'], 'file')
|
8
|
+
Dir.mkdir(dir) unless File.exists?(dir)
|
9
|
+
file = 'lib/file/temp.rb'
|
10
|
+
FileUtils.cp_r(file, dir, :verbose => true)
|
17
11
|
end
|
18
12
|
|
19
|
-
desc
|
20
|
-
task :
|
21
|
-
|
22
|
-
|
23
|
-
ruby 'extconf.rb'
|
24
|
-
sh "#{make}"
|
25
|
-
build_file = 'temp.' + Config::CONFIG['DLEXT']
|
26
|
-
Dir.mkdir('file') unless File.exists?('file')
|
27
|
-
FileUtils.cp(build_file, 'file')
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
desc "Install the file-temp package"
|
32
|
-
task :install => [:build] do
|
33
|
-
Dir.chdir('ext') do
|
34
|
-
make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make'
|
35
|
-
sh "#{make} install"
|
36
|
-
end
|
37
|
-
end
|
13
|
+
desc 'Build the gem'
|
14
|
+
task :gem do
|
15
|
+
spec = eval(IO.read('file-temp.gemspec'))
|
16
|
+
Gem::Builder.new(spec).build
|
38
17
|
|
39
|
-
desc
|
40
|
-
task :install_gem do
|
41
|
-
ruby 'file-temp.gemspec'
|
18
|
+
desc 'Install the file-temp library as a gem'
|
19
|
+
task :install_gem => [:gem] do
|
42
20
|
file = Dir["*.gem"].first
|
43
21
|
sh "gem install #{file}"
|
44
22
|
end
|
45
23
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
t.libs << 'ext'
|
50
|
-
t.test_files = FileList['test/tc_file_temp.rb']
|
24
|
+
Rake::TestTask.new do |t|
|
25
|
+
t.verbose = true
|
26
|
+
t.warning = true
|
51
27
|
end
|
data/file-temp.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'file-temp'
|
5
|
+
gem.version = '1.1.0'
|
6
|
+
gem.author = 'Daniel J. Berger'
|
7
|
+
gem.email = 'djberg96@gmail.com'
|
8
|
+
gem.homepage = 'http://www.rubyforge.org/projects/shards'
|
9
|
+
gem.summary = 'An alternative way to generate temp files'
|
10
|
+
gem.test_file = 'test/test_file_temp.rb'
|
11
|
+
gem.has_rdoc = true
|
12
|
+
gem.files = Dir['**/*'].delete_if{ |item| item.include?('CVS') }
|
13
|
+
|
14
|
+
gem.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
|
15
|
+
gem.rubyforge_project = 'shards'
|
16
|
+
gem.required_ruby_version = '>= 1.8.6'
|
17
|
+
|
18
|
+
gem.add_dependency('use', '>= 1.3.1')
|
19
|
+
gem.add_dependency('ffi', '>= 0.5.0')
|
20
|
+
gem.add_development_dependency('test-unit', '>= 2.0.3')
|
21
|
+
|
22
|
+
gem.description = <<-EOF
|
23
|
+
The file-temp library provides an alternative approach to generating
|
24
|
+
temporary files. Features included improved security, a superior
|
25
|
+
interface, and better support for MS Windows.
|
26
|
+
EOF
|
27
|
+
end
|
data/lib/file/temp.rb
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'ffi'
|
3
|
+
|
4
|
+
class File::Temp < File
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
# :stopdoc:
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# True if operating system is MS Windows
|
12
|
+
WINDOWS = Config::CONFIG['host_os'] =~ /mswin|win32|dos|cygwin|mingw/i
|
13
|
+
|
14
|
+
if WINDOWS
|
15
|
+
ffi_lib 'msvcrt'
|
16
|
+
|
17
|
+
attach_function '_close', [:int], :int
|
18
|
+
attach_function 'fclose', [:pointer], :int
|
19
|
+
attach_function '_fdopen', [:int, :string], :pointer
|
20
|
+
attach_function '_fileno', [:pointer], :int
|
21
|
+
attach_function '_mktemp', [:string], :string
|
22
|
+
attach_function '_open', [:string, :int, :int], :int
|
23
|
+
attach_function '_open_osfhandle', [:long, :int], :int
|
24
|
+
attach_function 'tmpnam', [:string], :string
|
25
|
+
attach_function '_umask', [:int], :int
|
26
|
+
|
27
|
+
ffi_lib 'kernel32'
|
28
|
+
|
29
|
+
attach_function 'CloseHandle', [:long], :bool
|
30
|
+
attach_function 'CreateFileA', [:string, :ulong, :ulong, :pointer, :ulong, :ulong, :ulong], :long
|
31
|
+
attach_function 'DeleteFileA', [:string], :bool
|
32
|
+
attach_function 'GetTempPathA', [:long, :string], :long
|
33
|
+
attach_function 'GetTempFileNameA', [:string, :string, :uint, :pointer], :uint
|
34
|
+
|
35
|
+
S_IWRITE = 128
|
36
|
+
S_IREAD = 256
|
37
|
+
BINARY = 0x8000
|
38
|
+
SHORT_LIVED = 0x1000
|
39
|
+
GENERIC_READ = 0x80000000
|
40
|
+
GENERIC_WRITE = 0x40000000
|
41
|
+
CREATE_ALWAYS = 2
|
42
|
+
|
43
|
+
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
44
|
+
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000
|
45
|
+
INVALID_HANDLE_VALUE = -1
|
46
|
+
else
|
47
|
+
attach_function 'fileno', [:pointer], :int
|
48
|
+
attach_function 'mkstemp', [:string], :int
|
49
|
+
attach_function 'umask', [:int], :int
|
50
|
+
attach_function 'tmpfile', [], :pointer
|
51
|
+
attach_function 'fclose', [:pointer], :int
|
52
|
+
attach_function 'tmpnam', [:string], :string
|
53
|
+
end
|
54
|
+
|
55
|
+
public
|
56
|
+
|
57
|
+
# :startdoc:
|
58
|
+
|
59
|
+
# The version of the file-temp library.
|
60
|
+
VERSION = '1.1.0'
|
61
|
+
|
62
|
+
if WINDOWS
|
63
|
+
# The temporary directory used on MS Windows.
|
64
|
+
TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['USERPROFILE'] || "C:\\Windows\\Temp"
|
65
|
+
else
|
66
|
+
# The temporary directory used on Unix.
|
67
|
+
TMPDIR = ENV['TEMP'] || ENV['TMP'] || ENV['TMPDIR'] || '/tmp'
|
68
|
+
end
|
69
|
+
|
70
|
+
public
|
71
|
+
|
72
|
+
# Creates a new, anonymous, temporary file in your File::Temp::TMPDIR
|
73
|
+
# directory
|
74
|
+
#
|
75
|
+
# If the +delete+ option is set to true (the default) then the temporary file
|
76
|
+
# will be deleted automatically as soon as all references to it are closed.
|
77
|
+
# Otherwise, the file will live on in your File::Temp::TMPDIR path.
|
78
|
+
#
|
79
|
+
# If the +delete+ option is set to false, then the file is not deleted. In
|
80
|
+
# addition, you can supply a string +template+ that the system replaces with
|
81
|
+
# a unique filename. This template should end with 3 to 6 'X' characters.
|
82
|
+
# The default template is 'rb_file_temp_XXXXXX'. In this case the temporary
|
83
|
+
# file lives in the directory where it was created.
|
84
|
+
#
|
85
|
+
# The +template+ argument is ignored if the +delete+ argument is true.
|
86
|
+
#
|
87
|
+
# Example:
|
88
|
+
#
|
89
|
+
# fh = File::Temp.new(true, 'rb_file_temp_XXXXXX') => file
|
90
|
+
# fh.puts 'hello world'
|
91
|
+
# fh.close
|
92
|
+
#
|
93
|
+
def initialize(delete = true, template = 'rb_file_temp_XXXXXX')
|
94
|
+
@fptr = nil
|
95
|
+
|
96
|
+
if delete
|
97
|
+
@fptr = tmpfile()
|
98
|
+
fd = WINDOWS ? _fileno(@fptr) : fileno(@fptr)
|
99
|
+
else
|
100
|
+
begin
|
101
|
+
if WINDOWS
|
102
|
+
template = _mktemp(template)
|
103
|
+
omask = _umask(077)
|
104
|
+
else
|
105
|
+
omask = umask(077)
|
106
|
+
end
|
107
|
+
fd = mkstemp(File.join(TMPDIR, template))
|
108
|
+
raise SystemCallError, 'mkstemp()' if fd < 0
|
109
|
+
ensure
|
110
|
+
WINDOWS ? _umask(omask) : umask(omask)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
super(fd, 'wb+')
|
115
|
+
end
|
116
|
+
|
117
|
+
# The close method was overridden to ensure the internal file pointer we
|
118
|
+
# created in the constructor is closed. It is otherwise identical to the
|
119
|
+
# File#close method.
|
120
|
+
#
|
121
|
+
def close
|
122
|
+
super
|
123
|
+
fclose(@fptr) if @fptr
|
124
|
+
end
|
125
|
+
|
126
|
+
# Generates a unique file name, prefixed with the value of the
|
127
|
+
# File::Temp::TMPDIR constant.
|
128
|
+
#
|
129
|
+
# Note that a file is not actually generated on the filesystem.
|
130
|
+
#
|
131
|
+
def self.temp_name
|
132
|
+
TMPDIR + tmpnam(nil) << '.tmp'
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
if WINDOWS
|
138
|
+
# The version of tmpfile() implemented by Microsoft is unacceptable.
|
139
|
+
# It attempts to write to C:\ (root) instead of a temporary directory.
|
140
|
+
# This is not only bad behavior, it won't work on Windows 7 and later
|
141
|
+
# without admin rights due to security restrictions.
|
142
|
+
#
|
143
|
+
# This is a custom implementation based on some code from the Cairo
|
144
|
+
# project.
|
145
|
+
#
|
146
|
+
def tmpfile
|
147
|
+
buf = 1.chr * 1024
|
148
|
+
|
149
|
+
if GetTempPathA(buf.length, buf) == 0
|
150
|
+
raise SystemCallError, 'GetTempPath()'
|
151
|
+
end
|
152
|
+
|
153
|
+
file_name = buf[ /^[^\0]*/ ].chop # remove trailing slash
|
154
|
+
buf = 1.chr * 1024
|
155
|
+
|
156
|
+
if GetTempFileNameA(file_name, 'rb_', 0, buf) == 0
|
157
|
+
raise SystemCallError, 'GetTempFileName()'
|
158
|
+
end
|
159
|
+
|
160
|
+
file_name = buf[ /^[^\0]*/ ]
|
161
|
+
|
162
|
+
handle = CreateFileA(
|
163
|
+
file_name,
|
164
|
+
GENERIC_READ | GENERIC_WRITE,
|
165
|
+
0,
|
166
|
+
nil,
|
167
|
+
CREATE_ALWAYS,
|
168
|
+
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
|
169
|
+
0
|
170
|
+
)
|
171
|
+
|
172
|
+
if handle == INVALID_HANDLE_VALUE
|
173
|
+
DeleteFileA(file_name)
|
174
|
+
raise SystemCallError, 'CreateFile()'
|
175
|
+
end
|
176
|
+
|
177
|
+
fd = _open_osfhandle(handle, 0)
|
178
|
+
|
179
|
+
if fd < 0
|
180
|
+
CloseHandle(handle)
|
181
|
+
raise SystemCallError, 'open_osfhandle()'
|
182
|
+
end
|
183
|
+
|
184
|
+
fp = _fdopen(fd, 'w+b')
|
185
|
+
|
186
|
+
if fp.nil?
|
187
|
+
_close(fd)
|
188
|
+
raise SystemCallError, 'fdopen()'
|
189
|
+
end
|
190
|
+
|
191
|
+
fp
|
192
|
+
end
|
193
|
+
|
194
|
+
# The MS C runtime does not define a mkstemp() function, so we've
|
195
|
+
# created one here.
|
196
|
+
#
|
197
|
+
def mkstemp(template)
|
198
|
+
flags = RDWR | BINARY | CREAT | EXCL | SHORT_LIVED
|
199
|
+
pmode = S_IREAD | S_IWRITE
|
200
|
+
|
201
|
+
fd = _open(template, flags, pmode)
|
202
|
+
|
203
|
+
raise SystemCallError, 'mkstemp()' if fd < 0
|
204
|
+
|
205
|
+
fd
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# For backwards compatability
|
211
|
+
FileTemp = File::Temp
|
@@ -0,0 +1,91 @@
|
|
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
|
+
gem 'test-unit'
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'file/temp'
|
12
|
+
require 'rbconfig'
|
13
|
+
|
14
|
+
class TC_File_Temp < Test::Unit::TestCase
|
15
|
+
def setup
|
16
|
+
@dir = File::Temp::TMPDIR
|
17
|
+
@template = 'file-temp-test-XXXXX'
|
18
|
+
@fh = nil
|
19
|
+
|
20
|
+
# Because Dir[] doesn't work right with backslashes
|
21
|
+
@dir = @dir.tr("\\", "/") if Config::CONFIG['host_os'] =~ /mswin|win32|dos|cygwin|mingw/i
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_file_temp_version
|
25
|
+
assert_equal('1.1.0', File::Temp::VERSION)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_file_temp_threaded
|
29
|
+
threads = []
|
30
|
+
assert_nothing_raised{ 100.times{ threads << Thread.new{ File::Temp.new }}}
|
31
|
+
assert_nothing_raised{ threads.join }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_file_temp_tmpdir
|
35
|
+
assert_not_nil(File::Temp::TMPDIR)
|
36
|
+
assert_kind_of(String, File::Temp::TMPDIR)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_file_temp_auto_delete
|
40
|
+
assert_nothing_raised{ @fh = File::Temp.new }
|
41
|
+
assert_nothing_raised{ @fh.print "hello" }
|
42
|
+
assert_nothing_raised{ @fh.close }
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_file_temp_no_delete
|
46
|
+
assert_nothing_raised{ @fh = File::Temp.new(false) }
|
47
|
+
assert_nothing_raised{ @fh.print "hello" }
|
48
|
+
assert_nothing_raised{ @fh.close }
|
49
|
+
assert_true(Dir["#{@dir}/rb_file_temp*"].length == 1)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_file_temp_no_delete_with_template
|
53
|
+
assert_nothing_raised{ File::Temp.new(false, 'temp_foo_XXXXXX').close }
|
54
|
+
assert_true(Dir["#{@dir}/temp_foo*"].length >= 1)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_file_temp_no_delete_with_block
|
58
|
+
assert_nothing_raised{ File::Temp.open(false, 'temp_foo_XXXXXX'){ |fh| fh.puts "hello" } }
|
59
|
+
assert_true(Dir["#{@dir}/temp_foo*"].length >= 1)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_file_temp_expected_errors
|
63
|
+
assert_raise(TypeError, ArgumentError){ @fh = File::Temp.new(false, 1) }
|
64
|
+
assert_raise(ArgumentError){ @fh = File::Temp.new(true, 'temp_bar_XXXXX', 1) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_file_temp_name_basic_functionality
|
68
|
+
assert_respond_to(File::Temp, :temp_name)
|
69
|
+
assert_nothing_raised{ File::Temp.temp_name }
|
70
|
+
assert_kind_of(String, File::Temp.temp_name)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_file_temp_name
|
74
|
+
assert_equal('.tmp', File.extname(File::Temp.temp_name))
|
75
|
+
end
|
76
|
+
|
77
|
+
def teardown
|
78
|
+
@dir = nil
|
79
|
+
@template = nil
|
80
|
+
@fh.close if @fh && !@fh.closed?
|
81
|
+
@fh = nil
|
82
|
+
|
83
|
+
Dir["temp_*"].each{ |f| File.delete(f) }
|
84
|
+
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
85
|
+
|
86
|
+
Dir.chdir(File::Temp::TMPDIR) do
|
87
|
+
Dir["temp_*"].each{ |f| File.delete(f) }
|
88
|
+
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file-temp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -9,30 +9,61 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-10-21 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: use
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.3.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: ffi
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.5.0
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: test-unit
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.0.3
|
44
|
+
version:
|
45
|
+
description: " The file-temp library provides an alternative approach to generating\n temporary files. Features included improved security, a superior\n interface, and better support for MS Windows.\n"
|
17
46
|
email: djberg96@gmail.com
|
18
47
|
executables: []
|
19
48
|
|
20
|
-
extensions:
|
21
|
-
|
49
|
+
extensions: []
|
50
|
+
|
22
51
|
extra_rdoc_files:
|
23
52
|
- CHANGES
|
24
53
|
- README
|
25
54
|
- MANIFEST
|
26
|
-
- ext/temp.c
|
27
55
|
files:
|
28
|
-
- test/tc_file_temp.rb
|
29
56
|
- CHANGES
|
57
|
+
- file-temp.gemspec
|
58
|
+
- lib/file/temp.rb
|
30
59
|
- MANIFEST
|
31
60
|
- Rakefile
|
32
61
|
- README
|
33
|
-
-
|
62
|
+
- test/test_file_temp.rb
|
34
63
|
has_rdoc: true
|
35
64
|
homepage: http://www.rubyforge.org/projects/shards
|
65
|
+
licenses: []
|
66
|
+
|
36
67
|
post_install_message:
|
37
68
|
rdoc_options: []
|
38
69
|
|
@@ -42,7 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
73
|
requirements:
|
43
74
|
- - ">="
|
44
75
|
- !ruby/object:Gem::Version
|
45
|
-
version: 1.8.
|
76
|
+
version: 1.8.6
|
46
77
|
version:
|
47
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
79
|
requirements:
|
@@ -53,9 +84,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
84
|
requirements: []
|
54
85
|
|
55
86
|
rubyforge_project: shards
|
56
|
-
rubygems_version: 1.
|
87
|
+
rubygems_version: 1.3.5
|
57
88
|
signing_key:
|
58
|
-
specification_version:
|
59
|
-
summary: An alternative way to generate
|
89
|
+
specification_version: 3
|
90
|
+
summary: An alternative way to generate temp files
|
60
91
|
test_files:
|
61
|
-
- test/
|
92
|
+
- test/test_file_temp.rb
|
data/ext/extconf.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'mkmf'
|
2
|
-
dir_config('tmpfile')
|
3
|
-
|
4
|
-
have_func('tmpfile_s')
|
5
|
-
have_func('_sopen_s')
|
6
|
-
|
7
|
-
unless have_func('tmpfile')
|
8
|
-
raise 'This library is not supported on your platform. Aborting'
|
9
|
-
end
|
10
|
-
|
11
|
-
have_func('mkstemp')
|
12
|
-
|
13
|
-
create_makefile('file/temp')
|
data/ext/temp.c
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <stdio.h>
|
3
|
-
#include <sys/stat.h>
|
4
|
-
|
5
|
-
#ifdef HAVE__SOPEN_S
|
6
|
-
#include <share.h>
|
7
|
-
#endif
|
8
|
-
|
9
|
-
#ifndef HAVE_MKSTEMP
|
10
|
-
#include <fcntl.h>
|
11
|
-
#include <temp.h>
|
12
|
-
#endif
|
13
|
-
|
14
|
-
#ifndef P_tmpdir
|
15
|
-
#define P_tmpdir "/tmp"
|
16
|
-
#endif
|
17
|
-
|
18
|
-
#define VERSION "1.0.0"
|
19
|
-
|
20
|
-
VALUE cFileTemp;
|
21
|
-
|
22
|
-
/* call-seq:
|
23
|
-
* FileTemp.new(delete = true, template = 'rb_file_temp_XXXXXX') => file
|
24
|
-
*
|
25
|
-
* Creates a new, anonymous temporary file in your FileTemp::TMPDIR directory,
|
26
|
-
* or /tmp if that cannot be accessed. If your $TMPDIR environment variable is
|
27
|
-
* set, it will be used instead. If $TMPDIR is not writable by the process, it
|
28
|
-
* will resort back to FileTemp::TMPDIR or /tmp.
|
29
|
-
*
|
30
|
-
* If the +delete+ option is set to true (the default) then the temporary file
|
31
|
-
* will be deleted automatically as soon as all references to it are closed.
|
32
|
-
* Otherwise, the file will live on in your $TMPDIR.
|
33
|
-
*
|
34
|
-
* If the +delete+ option is set to false, then the file is *not* deleted. In
|
35
|
-
* addition, you can supply a string +template+ that the system replaces with
|
36
|
-
* a unique filename. This template should end with 3 to 6 'X' characters.
|
37
|
-
* The default template is 'rb_file_temp_XXXXXX'. In this case the temporary
|
38
|
-
* file lives in the directory where it was created.
|
39
|
-
*
|
40
|
-
* The +template+ argument is ignored if the +delete+ argument is true.
|
41
|
-
*/
|
42
|
-
static VALUE tempfile_init(int argc, VALUE* argv, VALUE self){
|
43
|
-
VALUE v_args[2];
|
44
|
-
VALUE v_delete;
|
45
|
-
VALUE v_template;
|
46
|
-
|
47
|
-
rb_scan_args(argc, argv, "02", &v_delete, &v_template);
|
48
|
-
|
49
|
-
if(NIL_P(v_delete))
|
50
|
-
v_delete = Qtrue;
|
51
|
-
|
52
|
-
if(RTEST(v_delete)){
|
53
|
-
#ifdef HAVE_TMPFILE_S
|
54
|
-
FILE* fptr;
|
55
|
-
|
56
|
-
if(tmpfile_s(&fptr))
|
57
|
-
rb_sys_fail("tmpfile_s()");
|
58
|
-
#else
|
59
|
-
FILE* fptr = tmpfile();
|
60
|
-
if(!fptr)
|
61
|
-
rb_sys_fail("tmpfile()");
|
62
|
-
#endif
|
63
|
-
v_args[0] = INT2FIX(fileno(fptr));
|
64
|
-
}
|
65
|
-
else{
|
66
|
-
int fd, omask;
|
67
|
-
|
68
|
-
if(NIL_P(v_template))
|
69
|
-
v_template = rb_str_new2("rb_file_temp_XXXXXX");
|
70
|
-
|
71
|
-
/* Set the umask to improve security */
|
72
|
-
omask = umask(077);
|
73
|
-
fd = mkstemp(StringValuePtr(v_template));
|
74
|
-
umask(omask);
|
75
|
-
|
76
|
-
if(fd < 0)
|
77
|
-
rb_sys_fail("mkstemp()");
|
78
|
-
|
79
|
-
v_args[0] = INT2FIX(fd);
|
80
|
-
}
|
81
|
-
|
82
|
-
/* This bit of explicitness is necessary for MS Windows */
|
83
|
-
v_args[1] = rb_str_new2("wb+");
|
84
|
-
|
85
|
-
return rb_call_super(2, v_args);
|
86
|
-
}
|
87
|
-
|
88
|
-
/*
|
89
|
-
* Generates a unique file name, prefixed with the value of FileTemp::TMPDIR.
|
90
|
-
* Note that a file is not actually generated on the filesystem.
|
91
|
-
*/
|
92
|
-
static VALUE tempfile_tmpnam(VALUE klass){
|
93
|
-
char buf[L_tmpnam];
|
94
|
-
return rb_str_new2(tmpnam(buf));
|
95
|
-
}
|
96
|
-
|
97
|
-
void Init_temp(){
|
98
|
-
|
99
|
-
/* The FileTemp class creates managed temporary files. Unlike Ruby's
|
100
|
-
* Tempfile class from this standard library, this is a subclass of File.
|
101
|
-
* In addition, the temporary file is automatically deleted when all
|
102
|
-
* references to it are closed (instead of waiting until the Ruby process
|
103
|
-
* is complete).
|
104
|
-
*/
|
105
|
-
cFileTemp = rb_define_class("FileTemp", rb_cFile);
|
106
|
-
|
107
|
-
/* Instance Methods */
|
108
|
-
rb_define_method(cFileTemp, "initialize", tempfile_init, -1);
|
109
|
-
|
110
|
-
/* Singleton Methods */
|
111
|
-
rb_define_singleton_method(cFileTemp, "temp_name", tempfile_tmpnam, 0);
|
112
|
-
|
113
|
-
/* Constants */
|
114
|
-
|
115
|
-
/* ENV['P_tmpdir']: Your system's tmpdir */
|
116
|
-
rb_define_const(cFileTemp, "TMPDIR", rb_str_new2(P_tmpdir));
|
117
|
-
|
118
|
-
/* 0.1.3: The version of this library */
|
119
|
-
rb_define_const(cFileTemp, "VERSION", rb_str_new2(VERSION));
|
120
|
-
}
|
data/test/tc_file_temp.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
######################################################################
|
2
|
-
# tc_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 'test/unit'
|
8
|
-
require 'file/temp'
|
9
|
-
|
10
|
-
class TC_File_Temp < Test::Unit::TestCase
|
11
|
-
def setup
|
12
|
-
@template = 'file-temp-test-XXXXX'
|
13
|
-
@fh = nil
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_file_temp_version
|
17
|
-
assert_equal('1.0.0', FileTemp::VERSION)
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_file_temp_threaded
|
21
|
-
threads = []
|
22
|
-
assert_nothing_raised{ 100.times{ threads << Thread.new{ FileTemp.new }}}
|
23
|
-
assert_nothing_raised{ threads.join }
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_file_temp_tmpdir
|
27
|
-
assert_not_nil(FileTemp::TMPDIR)
|
28
|
-
assert_kind_of(String, FileTemp::TMPDIR)
|
29
|
-
unless RUBY_PLATFORM.match('mswin')
|
30
|
-
assert_equal(true, ['/tmp', '/var/tmp/'].include?(FileTemp::TMPDIR))
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_file_temp_auto_delete
|
35
|
-
assert_nothing_raised{ @fh = FileTemp.new }
|
36
|
-
assert_nothing_raised{ @fh.print "hello" }
|
37
|
-
assert_nothing_raised{ @fh.close }
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_file_temp_no_delete
|
41
|
-
assert_nothing_raised{ @fh = FileTemp.new(false) }
|
42
|
-
assert_equal(true, Dir["rb_file_temp*"].length == 1)
|
43
|
-
assert_nothing_raised{ @fh.print "hello" }
|
44
|
-
assert_nothing_raised{ @fh.close }
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_file_temp_no_delete_with_template
|
48
|
-
assert_nothing_raised{ @fh = FileTemp.new(false, 'temp_foo_XXXXX') }
|
49
|
-
assert_equal(true, Dir["temp_foo*"].length == 1)
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_file_temp_expected_errors
|
53
|
-
assert_raise(TypeError){ @fh = FileTemp.new(false, 1) }
|
54
|
-
assert_raise(ArgumentError){ @fh = FileTemp.new(true, 'temp_bar_XXXXX', 1) }
|
55
|
-
end
|
56
|
-
|
57
|
-
def teardown
|
58
|
-
@template = nil
|
59
|
-
@fh.close if @fh && !@fh.closed?
|
60
|
-
@fh = nil
|
61
|
-
Dir["temp_*"].each{ |f| File.delete(f) }
|
62
|
-
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
63
|
-
end
|
64
|
-
end
|