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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2fb1391ce05c64e9f018206c3619e691cf2a0e1f
|
4
|
+
data.tar.gz: ab155469cf49f1546b700d2d9aa874da22ae9d53
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 749a21db42342082d475e25025c496ea6ad5df1cb3965fdff3610b3a08ebc9e6c341ca863e3469c4b09056caa7ba05ce24aee2c9e3ddad7c1f47f53fd1cf31b2
|
7
|
+
data.tar.gz: 4349528879f6f62311bdfabee5cc2fe5fb30f3a194694809b3cfe53f46d7fd9ce9a48dc98475b7b1b85da1020f04e6d1429eac1f34c2ab084ce97eeef0af0540
|
data/CHANGES
CHANGED
@@ -1,50 +1,63 @@
|
|
1
|
-
= 1.2.
|
2
|
-
*
|
3
|
-
|
4
|
-
|
5
|
-
*
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
*
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
*
|
18
|
-
*
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
*
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
*
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
*
|
39
|
-
|
40
|
-
|
41
|
-
=
|
42
|
-
*
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
*
|
47
|
-
*
|
48
|
-
|
49
|
-
|
50
|
-
|
1
|
+
= 1.2.1 - 17-Feb-2014
|
2
|
+
* There is now a completely separate implementation for JRuby that uses the
|
3
|
+
Java API instead of C. It uses a GUID to create the temporary file name
|
4
|
+
instead of the 'XXXXXX' template, but is otherwise identical in function.
|
5
|
+
* Reworked the error handling. The posix functions now use a combination
|
6
|
+
of SystemCallError and FFI.errno, except on Windows, which uses _get_errno
|
7
|
+
instead for the posix compatible functions.
|
8
|
+
* Refactored the tests to use declarative syntax and added one test for
|
9
|
+
invalid templates.
|
10
|
+
* Removed the internal mkstemp function for Windows, no longer needed.
|
11
|
+
* Use tmpnam_s on Windows instead of tmpnam.
|
12
|
+
* Use wide character functions on Windows.
|
13
|
+
|
14
|
+
= 1.2.0 - 10-Apr-2012
|
15
|
+
* Removed the old FileTemp alias for File::Temp. It was deprecated and
|
16
|
+
has now been officially removed.
|
17
|
+
* Some refactoring of the custom internal Windows functions.
|
18
|
+
* Nicer error handling if certain FFI functions fail.
|
19
|
+
* Made the FFI functions private.
|
20
|
+
|
21
|
+
= 1.1.5 - 17-Jul-2011
|
22
|
+
* Now stores file path information if the file is retained on the filesystem.
|
23
|
+
Thanks go to joerixaop for the patch.
|
24
|
+
* The TMPDIR fallback determination on Windows is no longer hard coded.
|
25
|
+
|
26
|
+
= 1.1.4 - 16-Sep-2010
|
27
|
+
* The File::Temp.temp_name method has been altered on Unix systems. It
|
28
|
+
no longer prefixes TMPDIR to the name since it was redundant and could
|
29
|
+
generate a bogus path.
|
30
|
+
* Set the license to Artistic 2.0.
|
31
|
+
* Set the test task as the default Rake task.
|
32
|
+
|
33
|
+
= 1.1.3 - 14-Sep-2010
|
34
|
+
* Fixed potential libc linker failure.
|
35
|
+
|
36
|
+
= 1.1.2 - 28-Apr-2010
|
37
|
+
* Explicitly link against libc for Unix versions.
|
38
|
+
* Refactored the Rakefile. An old install task was removed and the gem
|
39
|
+
related tasks were placed under the 'gem' namespace.
|
40
|
+
|
41
|
+
= 1.1.1 - 24-Oct-2009
|
42
|
+
* Removed the 'use' library as a dependency.
|
43
|
+
|
44
|
+
= 1.1.0 - 21-Oct-2009
|
45
|
+
* Now pure Ruby, using FFI.
|
46
|
+
* Fixed RF Bug #26757 - FILE pointer leak. Thanks go to Eric Wong for the spot.
|
47
|
+
* Renamed and refactored the test file slightly.
|
48
|
+
* Updated the gemspec.
|
49
|
+
|
50
|
+
= 1.0.0 - 12-Apr-2008
|
51
|
+
* Added security via umask().
|
52
|
+
* Version bump to 1.0.0.
|
53
|
+
|
54
|
+
= 0.1.2 - 6-Jun-2007
|
55
|
+
* Gemspec fix (forgot the temp.h file - oops).
|
56
|
+
* Added an extra test.
|
57
|
+
|
58
|
+
= 0.1.1 - 2-Jun-2007
|
59
|
+
* Core code and test case now work properly on MS Windows.
|
60
|
+
* Now uses MS VC++ 8 functions when available (tmpfile_s, _sopen_s).
|
61
|
+
|
62
|
+
= 0.1.0 - 1-Jun-2007
|
63
|
+
* Initial release.
|
data/MANIFEST
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
* CHANGES
|
2
|
-
* MANIFEST
|
3
|
-
* README
|
4
|
-
* Rakefile
|
5
|
-
* file-temp.gemspec
|
6
|
-
* lib/file/temp.rb
|
7
|
-
*
|
1
|
+
* CHANGES
|
2
|
+
* MANIFEST
|
3
|
+
* README
|
4
|
+
* Rakefile
|
5
|
+
* file-temp.gemspec
|
6
|
+
* lib/file/temp.rb
|
7
|
+
* lib/file/temp_c.rb
|
8
|
+
* lib/file/temp_java.rb
|
9
|
+
* test/test_file_temp.rb
|
data/README
CHANGED
@@ -1,56 +1,61 @@
|
|
1
|
-
== Description
|
2
|
-
The file-temp library is an alternate way to handle tempfile generation.
|
3
|
-
|
4
|
-
== Requirements
|
5
|
-
ffi 0.
|
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.
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
==
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
1
|
+
== Description
|
2
|
+
The file-temp library is an alternate way to handle tempfile generation.
|
3
|
+
|
4
|
+
== Requirements
|
5
|
+
ffi 1.0.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.
|
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
|
+
The implementation for JRuby uses the Java API, not the C API. The
|
35
|
+
temporary file name generated by Java is different than the C version,
|
36
|
+
since it uses a GUID instead of the 'XXXXXX' template, but the
|
37
|
+
interface is otherwise identical.
|
38
|
+
|
39
|
+
There is one test failure with JRuby (threaded tempfile creation). I am
|
40
|
+
not sure why, as sample code seems to work fine. Help wanted.
|
41
|
+
|
42
|
+
== MS Windows
|
43
|
+
You may need to use the mingw build in order to use this library.
|
44
|
+
|
45
|
+
== License
|
46
|
+
Artistic 2.0
|
47
|
+
|
48
|
+
== Copyright
|
49
|
+
(C) 2007-2014 Daniel J. Berger
|
50
|
+
All Rights Reserved
|
51
|
+
|
52
|
+
== Warranty
|
53
|
+
This library is provided "as is" and without any express or
|
54
|
+
implied warranties, including, without limitation, the implied
|
55
|
+
warranties of merchantability and fitness for a particular purpose.
|
56
|
+
|
57
|
+
== Author
|
58
|
+
Daniel J. Berger
|
59
|
+
|
60
|
+
== See also
|
61
|
+
tmpfile(), mkstemp(), tmpnam()
|
data/Rakefile
CHANGED
@@ -1,61 +1,66 @@
|
|
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::
|
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
|
-
end
|
60
|
-
|
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', '**/*.tmp')
|
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
|
+
if Gem::VERSION < "2.0"
|
13
|
+
Gem::Builder.new(spec).build
|
14
|
+
else
|
15
|
+
require 'rubygems/package'
|
16
|
+
Gem::Package.build(spec)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Install the file-temp gem'
|
21
|
+
task :install => [:create] do
|
22
|
+
file = Dir["*.gem"].first
|
23
|
+
sh "gem install #{file}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Export the contents of the library to an archive. Note that this requires
|
28
|
+
# presence of the .gitattributes file in order to prevent the .git contents
|
29
|
+
# from being included.
|
30
|
+
#
|
31
|
+
# It also appears that I must add a trailing slash to the prefix manually.
|
32
|
+
# As of git 1.6.4.3 it does not automaticaly add it, despite what the docs
|
33
|
+
# say.
|
34
|
+
#
|
35
|
+
namespace 'export' do
|
36
|
+
spec = eval(IO.read('file-temp.gemspec'))
|
37
|
+
file = 'file-temp-' + spec.version.to_s
|
38
|
+
pref = file + '/' # Git does not add the trailing slash, despite what the docs say.
|
39
|
+
|
40
|
+
desc 'Export to a .tar.gz file'
|
41
|
+
task :gzip => [:clean] do
|
42
|
+
file += '.tar'
|
43
|
+
sh "git archive --prefix #{pref} --output #{file} master"
|
44
|
+
sh "gzip #{file}"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'Export to a .tar.bz2 file'
|
48
|
+
task :bzip2 => [:clean] do
|
49
|
+
file += '.tar'
|
50
|
+
sh "git archive --prefix #{pref} --output #{file} master"
|
51
|
+
sh "bzip2 -f #{file}"
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Export to a .zip file'
|
55
|
+
task :zip => [:clean] do
|
56
|
+
file += '.zip'
|
57
|
+
sh "git archive --prefix #{pref} --output #{file} --format zip master"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Rake::TestTask.new do |t|
|
62
|
+
t.verbose = true
|
63
|
+
t.warning = true
|
64
|
+
end
|
65
|
+
|
66
|
+
task :default => :test
|
data/file-temp.gemspec
CHANGED
@@ -1,26 +1,27 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
Gem::Specification.new do |spec|
|
4
|
-
spec.name = 'file-temp'
|
5
|
-
spec.version = '1.2.
|
6
|
-
spec.author = 'Daniel J. Berger'
|
7
|
-
spec.license = 'Artistic 2.0'
|
8
|
-
spec.email = 'djberg96@gmail.com'
|
9
|
-
spec.homepage = 'http://
|
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'
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'file-temp'
|
5
|
+
spec.version = '1.2.1'
|
6
|
+
spec.author = 'Daniel J. Berger'
|
7
|
+
spec.license = 'Artistic 2.0'
|
8
|
+
spec.email = 'djberg96@gmail.com'
|
9
|
+
spec.homepage = 'http://github.com/djberg96/file-temp'
|
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')
|
20
|
+
spec.add_development_dependency('rake')
|
21
|
+
|
22
|
+
spec.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
CHANGED
@@ -1,254 +1,5 @@
|
|
1
|
-
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
1
|
+
if RUBY_PLATFORM == 'java'
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'temp_java')
|
3
|
+
else
|
4
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'temp_c')
|
5
|
+
end
|