io-extra 1.0.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.
- data/CHANGES +10 -0
- data/README +39 -0
- data/doc/io_extra.txt +89 -0
- data/extconf.rb +10 -0
- data/lib/io/extra.c +147 -0
- data/test/tc_ioextra.rb +65 -0
- metadata +51 -0
data/CHANGES
ADDED
data/README
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
= Description
|
2
|
+
The io-extra package provides a few extra IO methods that you may find
|
3
|
+
handy. They are IO.closefrom, IO.fdwalk, IO#directio? and IO#directio=.
|
4
|
+
|
5
|
+
Not supported on MS Windows.
|
6
|
+
|
7
|
+
= Installation
|
8
|
+
ruby extconf.rb
|
9
|
+
make
|
10
|
+
ruby test/tc_ioextra.rb (optional)
|
11
|
+
make site-install
|
12
|
+
|
13
|
+
= Developer's Notes
|
14
|
+
== Q) What is the difference between your implementation of IO.closefrom and a
|
15
|
+
pure Ruby version that looks something like this?
|
16
|
+
|
17
|
+
def IO.closefrom(n)
|
18
|
+
0.upto n do |fd|
|
19
|
+
IO.for_fd(fd).close
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
The primary difference is that this walks all file descriptors, rather
|
24
|
+
than only open file descriptors. However, I should note that this only
|
25
|
+
applies if your platform supports the closefrom() function. In that case,
|
26
|
+
the only advantage is speed.
|
27
|
+
|
28
|
+
== Q) What is the difference between your implementation of IO.fdwalk and a
|
29
|
+
pure Ruby version that looks something like this?
|
30
|
+
|
31
|
+
def IO.fdwalk(n)
|
32
|
+
ObjectSpace.each_object(File){ |f|
|
33
|
+
yield f if f.fileno >= n
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
The primary difference is that this only closes Ruby file objects, not
|
38
|
+
necessarily every filehandle opened by the Ruby process. Think system(), for
|
39
|
+
example.
|
data/doc/io_extra.txt
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
= Description
|
2
|
+
The io-extra package provides a few extra IO methods that you may find
|
3
|
+
handy. They are IO.closefrom, IO.fdwalk and IO.directio.
|
4
|
+
|
5
|
+
Not supported on Win32.
|
6
|
+
|
7
|
+
= Synopsis
|
8
|
+
require "io/extra"
|
9
|
+
|
10
|
+
# Print the fileno of each file handle and then close it
|
11
|
+
IO.fdwalk(0){ |fh|
|
12
|
+
p fh.fileno
|
13
|
+
fh.close
|
14
|
+
}
|
15
|
+
|
16
|
+
# Close all file handles with a fileno greater than or equal to 2.
|
17
|
+
IO.closefrom(2)
|
18
|
+
|
19
|
+
= Class Methods
|
20
|
+
IO.closefrom(low_fd)
|
21
|
+
Closes all open file descriptors greater than or equal to 'low_fd'.
|
22
|
+
|
23
|
+
This uses your systems native closefrom() function, if supported. If not,
|
24
|
+
this method uses a slightly less efficient manual approach that uses
|
25
|
+
getrlimit() behind the scenes.
|
26
|
+
|
27
|
+
IO.fdwalk(low_fd){ |fh| ... }
|
28
|
+
Iterates over each open file descriptor and yields back a File object.
|
29
|
+
Note that it is up to you to close file handles, if desired, when this
|
30
|
+
method is used.
|
31
|
+
|
32
|
+
Not supported by all platforms.
|
33
|
+
|
34
|
+
= Instance methods
|
35
|
+
IO#directio?
|
36
|
+
Returns true or false, based on whether directio has been set for the
|
37
|
+
current handle. The default is false.
|
38
|
+
|
39
|
+
Note supported on all platforms.
|
40
|
+
|
41
|
+
IO#directio=(io_const)
|
42
|
+
Sets the advice for the current file descriptor using directio(). Valid
|
43
|
+
values are IO::DIRECTIO_ON and IO::DIRECTIO_OFF.
|
44
|
+
|
45
|
+
All file descriptors start at DIRECTIO_OFF, unless your filesystem has
|
46
|
+
been mounted using 'forcedirectio' (and supports that option).
|
47
|
+
|
48
|
+
Not supported on all platforms
|
49
|
+
|
50
|
+
= Constants
|
51
|
+
IO::DIRECTIO_ON
|
52
|
+
This value can be passed to IO#directio= in order to turn directio on for
|
53
|
+
the given file handle.
|
54
|
+
|
55
|
+
This value is only defined if your platform supports the directio()
|
56
|
+
function.
|
57
|
+
IO::DIRECTIO_OFF
|
58
|
+
This value can be passed to IO#directio= in order to turn directio off for
|
59
|
+
the given file handle.
|
60
|
+
|
61
|
+
This value is only defined if your platform supports the directio()
|
62
|
+
function.
|
63
|
+
|
64
|
+
IO::EXTRA_VERSION
|
65
|
+
Returns the current version number of this package as a String.
|
66
|
+
|
67
|
+
= Known Bugs
|
68
|
+
You may receive a warning about implicit declaration during the build
|
69
|
+
process. You can ignore this.
|
70
|
+
|
71
|
+
= Future Plans
|
72
|
+
Eliminate warnings that occur during the build process.
|
73
|
+
|
74
|
+
= License
|
75
|
+
Ruby's
|
76
|
+
|
77
|
+
= Copyright
|
78
|
+
(C) 2003-2005 Daniel J. Berger
|
79
|
+
All Rights Reserved
|
80
|
+
|
81
|
+
= Warranty
|
82
|
+
This package is provided "as is" and without any express or
|
83
|
+
implied warranties, including, without limitation, the implied
|
84
|
+
warranties of merchantability and fitness for a particular purpose.
|
85
|
+
|
86
|
+
= Author
|
87
|
+
Daniel J. Berger
|
88
|
+
djberg96 at gmail dot com
|
89
|
+
imperator on IRC (irc.freenode.net)
|
data/extconf.rb
ADDED
data/lib/io/extra.c
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
/* Extra methods for the IO class */
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "rubyio.h"
|
4
|
+
#include <unistd.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
|
7
|
+
#ifndef HAVE_CLOSEFROM
|
8
|
+
#include <sys/resource.h>
|
9
|
+
#endif
|
10
|
+
|
11
|
+
#ifdef HAVE_DIRECTIO
|
12
|
+
#include <sys/types.h>
|
13
|
+
#include <sys/fcntl.h>
|
14
|
+
#endif
|
15
|
+
|
16
|
+
/*
|
17
|
+
* call-seq:
|
18
|
+
* IO.closefrom(lowfd)
|
19
|
+
*
|
20
|
+
* Close all open file descriptors (associated with the current process) that
|
21
|
+
* are greater than or equal to +lowfd+.
|
22
|
+
*
|
23
|
+
* This method uses your system's builtin closefrom() function, if supported.
|
24
|
+
* Otherwise, it uses a manual, and (probably) less efficient approach.
|
25
|
+
*
|
26
|
+
*--
|
27
|
+
* The manual approach was copied from the closefrom() man page on Solaris 9.
|
28
|
+
*/
|
29
|
+
static VALUE io_closefrom(VALUE klass, VALUE v_low_fd){
|
30
|
+
#ifdef HAVE_CLOSEFROM
|
31
|
+
closefrom(NUM2INT(v_low_fd));
|
32
|
+
#else
|
33
|
+
int i, lowfd;
|
34
|
+
struct rlimit limits;
|
35
|
+
getrlimit(RLIMIT_NOFILE, &limits);
|
36
|
+
lowfd = NUM2INT(v_low_fd);
|
37
|
+
|
38
|
+
for(i = lowfd; i < limits.rlim_max; i++){
|
39
|
+
close(i);
|
40
|
+
}
|
41
|
+
#endif
|
42
|
+
return klass;
|
43
|
+
}
|
44
|
+
|
45
|
+
/*
|
46
|
+
* Used by io_fdwalk. Yields a File object back to the block.
|
47
|
+
* It's up to the user to close it.
|
48
|
+
*/
|
49
|
+
static int close_func(void* lowfd, int fd){
|
50
|
+
VALUE v_args[1];
|
51
|
+
|
52
|
+
v_args[0] = UINT2NUM(fd);
|
53
|
+
rb_yield(rb_class_new_instance(1, v_args, rb_cFile));
|
54
|
+
return 0;
|
55
|
+
}
|
56
|
+
|
57
|
+
#ifdef HAVE_FDWALK
|
58
|
+
/*
|
59
|
+
* call-seq:
|
60
|
+
* IO.fdwalk(lowfd){ |fh| ... }
|
61
|
+
*
|
62
|
+
* Iterates over each open file descriptor and yields back a File object.
|
63
|
+
*
|
64
|
+
* Not supported on all platforms.
|
65
|
+
*/
|
66
|
+
static VALUE io_fdwalk(int argc, VALUE* argv, VALUE klass){
|
67
|
+
VALUE v_low_fd, v_block;
|
68
|
+
int lowfd;
|
69
|
+
|
70
|
+
rb_scan_args(argc, argv, "1&", &v_low_fd, &v_block);
|
71
|
+
lowfd = NUM2INT(v_low_fd);
|
72
|
+
|
73
|
+
fdwalk(close_func, &lowfd);
|
74
|
+
|
75
|
+
return klass;
|
76
|
+
}
|
77
|
+
#endif
|
78
|
+
|
79
|
+
#ifdef HAVE_DIRECTIO
|
80
|
+
/*
|
81
|
+
* call-seq:
|
82
|
+
* IO#directio?
|
83
|
+
*
|
84
|
+
* Returns true or false, based on whether directio has been set for the
|
85
|
+
* current handle. The default is false.
|
86
|
+
*/
|
87
|
+
static VALUE io_get_directio(VALUE self){
|
88
|
+
VALUE v_advice = rb_iv_get(self, "directio");
|
89
|
+
|
90
|
+
if(NIL_P(v_advice))
|
91
|
+
v_advice = Qfalse;
|
92
|
+
|
93
|
+
return v_advice;
|
94
|
+
}
|
95
|
+
|
96
|
+
/*
|
97
|
+
* call-seq:
|
98
|
+
* IO#directio=(advice)
|
99
|
+
*
|
100
|
+
* Sets the advice for the current file descriptor using directio(). Valid
|
101
|
+
* values are IO::DIRECTIO_ON and IO::DIRECTIO_OFF.
|
102
|
+
*
|
103
|
+
* All file descriptors start at DIRECTIO_OFF, unless your filesystem has
|
104
|
+
* been mounted using 'forcedirectio' (and supports that option).
|
105
|
+
*/
|
106
|
+
static VALUE io_set_directio(VALUE self, VALUE v_advice){
|
107
|
+
int fd, rv;
|
108
|
+
int advice = NUM2INT(v_advice);
|
109
|
+
|
110
|
+
/* Only two possible valid values */
|
111
|
+
if( (advice != DIRECTIO_OFF) && (advice != DIRECTIO_ON) )
|
112
|
+
rb_raise(rb_eStandardError, "Invalid value passed to IO#directio=");
|
113
|
+
|
114
|
+
/* Retrieve the current file descriptor in order to pass it to directio() */
|
115
|
+
fd = NUM2INT(rb_funcall(self, rb_intern("fileno"), 0, 0));
|
116
|
+
|
117
|
+
rv = directio(fd, advice);
|
118
|
+
|
119
|
+
if(-1 == rv)
|
120
|
+
rb_raise(rb_eStandardError, "The directio() call failed");
|
121
|
+
|
122
|
+
if(advice == DIRECTIO_ON)
|
123
|
+
rb_iv_set(self, "directio", Qtrue);
|
124
|
+
|
125
|
+
return self;
|
126
|
+
}
|
127
|
+
#endif
|
128
|
+
|
129
|
+
/* Adds the IO.closefrom, IO.fdwalk class methods, as well as the IO#directio
|
130
|
+
* and IO#directio? instance methods (if supported on your platform).
|
131
|
+
*/
|
132
|
+
void Init_extra(){
|
133
|
+
rb_define_singleton_method(rb_cIO, "closefrom", io_closefrom, 1);
|
134
|
+
|
135
|
+
#ifdef HAVE_FDWALK
|
136
|
+
rb_define_singleton_method(rb_cIO, "fdwalk", io_fdwalk, -1);
|
137
|
+
#endif
|
138
|
+
|
139
|
+
#ifdef HAVE_DIRECTIO
|
140
|
+
rb_define_method(rb_cIO, "directio?", io_get_directio, 0);
|
141
|
+
rb_define_method(rb_cIO, "directio=", io_set_directio, 1);
|
142
|
+
rb_define_const(rb_cIO, "DIRECTIO_OFF", UINT2NUM(DIRECTIO_OFF));
|
143
|
+
rb_define_const(rb_cIO, "DIRECTIO_ON", UINT2NUM(DIRECTIO_ON));
|
144
|
+
#endif
|
145
|
+
|
146
|
+
rb_define_const(rb_cIO, "EXTRA_VERSION", rb_str_new2("1.0.1"));
|
147
|
+
}
|
data/test/tc_ioextra.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#################################################
|
2
|
+
# tc_ioextra.rb
|
3
|
+
#
|
4
|
+
# Test suite for the io-extra package.
|
5
|
+
#################################################
|
6
|
+
base = File.basename(Dir.pwd)
|
7
|
+
|
8
|
+
if base == "test" || base =~ /io-extra/
|
9
|
+
require "ftools"
|
10
|
+
Dir.chdir("..") if base == "test"
|
11
|
+
Dir.mkdir("io") rescue nil
|
12
|
+
File.copy("extra.so","io")
|
13
|
+
$LOAD_PATH.unshift(Dir.pwd)
|
14
|
+
Dir.chdir("test") rescue nil
|
15
|
+
end
|
16
|
+
|
17
|
+
require "test/unit"
|
18
|
+
require "io/extra"
|
19
|
+
|
20
|
+
class TC_IO_Extra < Test::Unit::TestCase
|
21
|
+
def setup
|
22
|
+
@file = "delete_this.txt"
|
23
|
+
@fh = File.open(@file,"w+")
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_version
|
27
|
+
assert_equal("1.0.1", IO::EXTRA_VERSION)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_directio
|
31
|
+
assert_respond_to(@fh,:directio?)
|
32
|
+
assert_nothing_raised{ @fh.directio? }
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_directio_set
|
36
|
+
assert_respond_to(@fh,:directio=)
|
37
|
+
assert_raises(StandardError){ @fh.directio = 99 }
|
38
|
+
assert_nothing_raised{ @fh.directio = IO::DIRECTIO_ON }
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_closefrom
|
42
|
+
assert_respond_to(IO,:closefrom)
|
43
|
+
assert_nothing_raised{ IO.closefrom(3) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_fdwalk
|
47
|
+
assert_respond_to(IO,:fdwalk)
|
48
|
+
assert_nothing_raised{ IO.fdwalk(0){ } }
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_constants
|
52
|
+
assert_not_nil(IO::DIRECTIO_ON)
|
53
|
+
assert_not_nil(IO::DIRECTIO_OFF)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Ignore EBADF, since some of the tests will close @fh
|
57
|
+
def teardown
|
58
|
+
begin
|
59
|
+
@fh.close
|
60
|
+
rescue Errno::EBADF
|
61
|
+
end
|
62
|
+
@fh = nil
|
63
|
+
File.delete(@file) if File.exists?(@file)
|
64
|
+
end
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: io-extra
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.1
|
7
|
+
date: 2006-07-07 00:00:00 -06:00
|
8
|
+
summary: Adds the IO.closefrom and IO.fdwalk class methods as well as the IO#directio and IO#directio? instance methods (for those platforms that support them).
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: djberg96@gmail.com
|
12
|
+
homepage: http://www.rubyforge.org/projects/shards
|
13
|
+
rubyforge_project: shards
|
14
|
+
description: Adds the IO.closefrom and IO.fdwalk class methods as well as the IO#directio and IO#directio? instance methods (for those platforms that support them).
|
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
|
+
- doc/io_extra.txt
|
33
|
+
- test/tc_ioextra.rb
|
34
|
+
- lib/io/extra.c
|
35
|
+
- CHANGES
|
36
|
+
- README
|
37
|
+
test_files:
|
38
|
+
- test/tc_ioextra.rb
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- CHANGES
|
43
|
+
- README
|
44
|
+
executables: []
|
45
|
+
|
46
|
+
extensions:
|
47
|
+
- extconf.rb
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
dependencies: []
|
51
|
+
|