file-temp 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +2 -0
- data/MANIFEST +8 -0
- data/README +56 -0
- data/Rakefile +51 -0
- data/ext/extconf.rb +10 -0
- data/ext/temp.c +106 -0
- data/test/tc_file_temp.rb +55 -0
- metadata +54 -0
data/CHANGES
ADDED
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
= Description
|
2
|
+
The file-temp library is an alternate way to handle tempfile generation.
|
3
|
+
|
4
|
+
= Synopsis
|
5
|
+
require 'file/temp'
|
6
|
+
|
7
|
+
fh = FileTemp.new
|
8
|
+
fh.puts "hello"
|
9
|
+
fh.close # => Tempfile automatically deleted
|
10
|
+
|
11
|
+
fh = FileTemp.new(false)
|
12
|
+
fh.puts "world"
|
13
|
+
fh.close # => Tempfile still on your filesystem
|
14
|
+
|
15
|
+
= Installation
|
16
|
+
== Standard Installation
|
17
|
+
rake test (optional)
|
18
|
+
rake install
|
19
|
+
|
20
|
+
== Gem Installation
|
21
|
+
rake test (optional)
|
22
|
+
rake gem_install
|
23
|
+
|
24
|
+
= Motivation
|
25
|
+
Ruby's tempfile.rb is overwrought and susceptible to race conditions. This
|
26
|
+
This library uses your system's native tmpfile() or mkstemp() functions
|
27
|
+
instead of trying to handle race conditions manually via pure Ruby.
|
28
|
+
|
29
|
+
= Other libraries
|
30
|
+
I am aware of Cian Synnott's ruby-stemp project. However, I don't like the
|
31
|
+
interface, it's GNU-centric (which causes portability issues), and Cian
|
32
|
+
has disabled all the trackers and mailing lists on the RubyForge project
|
33
|
+
site, as well as online SCM access. So, if he doesn't want feedback, I'm
|
34
|
+
not going to waste time with it.
|
35
|
+
|
36
|
+
= Future Plans
|
37
|
+
I plan on adding MS Windows support in the next release.
|
38
|
+
|
39
|
+
= License
|
40
|
+
Ruby's
|
41
|
+
|
42
|
+
= Copyright
|
43
|
+
(C) 2007 Daniel J. Berger
|
44
|
+
All Rights Reserved
|
45
|
+
|
46
|
+
= Warranty
|
47
|
+
This package is provided "as is" and without any express or
|
48
|
+
implied warranties, including, without limitation, the implied
|
49
|
+
warranties of merchantability and fitness for a particular purpose.
|
50
|
+
|
51
|
+
= Author
|
52
|
+
Daniel J. Berger
|
53
|
+
djberg96 at gmail dot com
|
54
|
+
|
55
|
+
= See also
|
56
|
+
tmpfile(), mkstemp(), tmpnam()
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
desc "Clean the build files for the file-temp source for UNIX filetems"
|
6
|
+
task :clean do
|
7
|
+
make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make'
|
8
|
+
Dir.chdir('ext') do
|
9
|
+
FileUtils.rm_rf('file') if File.exists?('file')
|
10
|
+
build_file = 'temp.' + Config::CONFIG['DLEXT']
|
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
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Build the file-temp package on UNIX filetems (but don't install it)"
|
20
|
+
task :build => [:clean] do
|
21
|
+
make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make'
|
22
|
+
Dir.chdir('ext') do
|
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
|
38
|
+
|
39
|
+
desc "Install the file-temp package as a gem"
|
40
|
+
task :install_gem do
|
41
|
+
ruby 'file-temp.gemspec'
|
42
|
+
file = Dir["*.gem"].first
|
43
|
+
sh "gem install #{file}"
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Run the test suite"
|
47
|
+
Rake::TestTask.new("test") do |t|
|
48
|
+
task :test => :build
|
49
|
+
t.libs << 'ext'
|
50
|
+
t.test_files = FileList['test/tc_file_temp.rb']
|
51
|
+
end
|
data/ext/extconf.rb
ADDED
data/ext/temp.c
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
|
4
|
+
#ifndef HAVE_MKSTEMP
|
5
|
+
#include <fcntl.h>
|
6
|
+
#include <temp.h>
|
7
|
+
#endif
|
8
|
+
|
9
|
+
#ifdef HAVE__SOPEN_S
|
10
|
+
#include <share.h>
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#define VERSION "0.1.0"
|
14
|
+
|
15
|
+
VALUE cFileTemp;
|
16
|
+
|
17
|
+
/* call-seq:
|
18
|
+
* FileTemp.new(delete = true, template = 'rb_file_temp_XXXXXX') => file
|
19
|
+
*
|
20
|
+
* Creates a new, anonymous temporary file in your FileTemp::TMPDIR directory,
|
21
|
+
* or /tmp if that cannot be accessed. If your $TMPDIR environment variable is
|
22
|
+
* set, it will be used instead. If $TMPDIR is not writable by the process, it
|
23
|
+
* will resort back to FileTemp::TMPDIR or /tmp.
|
24
|
+
*
|
25
|
+
* If the +delete+ option is set to true (the default) then the temporary file
|
26
|
+
* will be deleted automatically as soon as all references to it are closed.
|
27
|
+
* Otherwise, the file will live on in your $TMPDIR.
|
28
|
+
*
|
29
|
+
* If the +delete+ option is set to false, then the file is *not* deleted. In
|
30
|
+
* addition, you can supply a string +template+ that the system replaces with
|
31
|
+
* a unique filename. This template should end with 3 to 6 'X' characters.
|
32
|
+
* The default template is 'rb_file_temp_XXXXXX'. In this case the temporary
|
33
|
+
* file lives in the directory where it was created.
|
34
|
+
*
|
35
|
+
* The +template+ argument is ignored if the +delete+ argument is true.
|
36
|
+
*/
|
37
|
+
static VALUE tempfile_init(int argc, VALUE* argv, VALUE self){
|
38
|
+
VALUE v_args[1];
|
39
|
+
VALUE v_delete;
|
40
|
+
VALUE v_template;
|
41
|
+
|
42
|
+
rb_scan_args(argc, argv, "02", &v_delete, &v_template);
|
43
|
+
|
44
|
+
if(NIL_P(v_delete))
|
45
|
+
v_delete = Qtrue;
|
46
|
+
|
47
|
+
if(RTEST(v_delete)){
|
48
|
+
FILE* fptr = tmpfile();
|
49
|
+
if(!fptr)
|
50
|
+
rb_sys_fail("tmpfile()");
|
51
|
+
|
52
|
+
v_args[0] = INT2FIX(fileno(fptr));
|
53
|
+
}
|
54
|
+
else{
|
55
|
+
int fd;
|
56
|
+
char buf[L_tmpnam];
|
57
|
+
|
58
|
+
if(NIL_P(v_template))
|
59
|
+
v_template = rb_str_new2("rb_file_temp_XXXXXX");
|
60
|
+
|
61
|
+
fd = mkstemp(StringValuePtr(v_template));
|
62
|
+
|
63
|
+
if(fd < 0)
|
64
|
+
rb_sys_fail("mkstemp()");
|
65
|
+
|
66
|
+
v_args[0] = INT2FIX(fd);
|
67
|
+
v_args[0] = INT2FIX(fd);
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
return rb_call_super(1, v_args);
|
72
|
+
}
|
73
|
+
|
74
|
+
/*
|
75
|
+
* Generates a unique file name, prefixed with the value of FileTemp::TMPDIR.
|
76
|
+
* Note that a file is not actually generated on the filesystem.
|
77
|
+
*/
|
78
|
+
static VALUE tempfile_tmpnam(VALUE klass){
|
79
|
+
char buf[L_tmpnam];
|
80
|
+
return rb_str_new2(tmpnam(buf));
|
81
|
+
}
|
82
|
+
|
83
|
+
void Init_temp(){
|
84
|
+
|
85
|
+
/* The FileTemp class creates managed temporary files. Unlike Ruby's
|
86
|
+
* Tempfile class from this standard library, this is a subclass of File.
|
87
|
+
* In addition, the temporary file is automatically deleted when all
|
88
|
+
* references to it are closed (instead of waiting until the Ruby process
|
89
|
+
* is complete).
|
90
|
+
*/
|
91
|
+
cFileTemp = rb_define_class("FileTemp", rb_cFile);
|
92
|
+
|
93
|
+
/* Instance Methods */
|
94
|
+
rb_define_method(cFileTemp, "initialize", tempfile_init, -1);
|
95
|
+
|
96
|
+
/* Singleton Methods */
|
97
|
+
rb_define_singleton_method(cFileTemp, "tmpnam", tempfile_tmpnam, 0);
|
98
|
+
|
99
|
+
/* Constants */
|
100
|
+
|
101
|
+
/* ENV['P_tmpdir']: Your system's tmpdir */
|
102
|
+
rb_define_const(cFileTemp, "TMPDIR", rb_str_new2(P_tmpdir));
|
103
|
+
|
104
|
+
/* 0.1.0: The version of this library */
|
105
|
+
rb_define_const(cFileTemp, "VERSION", rb_str_new2(VERSION));
|
106
|
+
}
|
@@ -0,0 +1,55 @@
|
|
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('0.1.0', FileTemp::VERSION)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_file_temp_tmpdir
|
21
|
+
assert_not_nil(FileTemp::TMPDIR)
|
22
|
+
assert_kind_of(String, FileTemp::TMPDIR)
|
23
|
+
assert_equal(true, ['/tmp', '/var/tmp/'].include?(FileTemp::TMPDIR))
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_file_temp_auto_delete
|
27
|
+
assert_nothing_raised{ @fh = FileTemp.new }
|
28
|
+
assert_nothing_raised{ @fh.print "hello" }
|
29
|
+
assert_nothing_raised{ @fh.close }
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_file_temp_no_delete
|
33
|
+
assert_nothing_raised{ @fh = FileTemp.new(false) }
|
34
|
+
assert_equal(true, Dir["rb_file_temp*"].length == 1)
|
35
|
+
assert_nothing_raised{ @fh.print "hello" }
|
36
|
+
assert_nothing_raised{ @fh.close }
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_file_temp_no_delete_with_template
|
40
|
+
assert_nothing_raised{ FileTemp.new(false, 'temp_foo_XXXXX') }
|
41
|
+
assert_equal(true, Dir["temp_foo*"].length == 1)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_file_temp_expected_errors
|
45
|
+
assert_raises(ArgumentError){ FileTemp.new(true, 'temp_bar_XXXXX', 1) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def teardown
|
49
|
+
@template = nil
|
50
|
+
@fh.close if @fh rescue nil # Ignore closed streams
|
51
|
+
@fh = nil
|
52
|
+
Dir["temp_*"].each{ |f| File.delete(f) }
|
53
|
+
Dir["rb_file_temp_*"].each{ |f| File.delete(f) }
|
54
|
+
end
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: file-temp
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-06-01 00:00:00 -06:00
|
8
|
+
summary: An alternative way to generate tempfiles
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: djberg96@gmail.com
|
12
|
+
homepage: http://www.rubyforge.org/projects/shards
|
13
|
+
rubyforge_project: shards
|
14
|
+
description: An alternative way to generate tempfiles
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Daniel J. Berger
|
31
|
+
files:
|
32
|
+
- test/tc_file_temp.rb
|
33
|
+
- CHANGES
|
34
|
+
- MANIFEST
|
35
|
+
- Rakefile
|
36
|
+
- README
|
37
|
+
- ext/temp.c
|
38
|
+
test_files:
|
39
|
+
- test/tc_file_temp.rb
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- CHANGES
|
44
|
+
- README
|
45
|
+
- MANIFEST
|
46
|
+
- ext/temp.c
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions:
|
50
|
+
- ext/extconf.rb
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
dependencies: []
|
54
|
+
|