io-extra 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/CHANGES +10 -0
  2. data/README +39 -0
  3. data/doc/io_extra.txt +89 -0
  4. data/extconf.rb +10 -0
  5. data/lib/io/extra.c +147 -0
  6. data/test/tc_ioextra.rb +65 -0
  7. metadata +51 -0
data/CHANGES ADDED
@@ -0,0 +1,10 @@
1
+ == 1.0.1 - 7-Jul-2006
2
+ * Added a gemspec.
3
+ * Added or improved the inline rdoc comments in the source.
4
+
5
+ == 1.0.0 - 16-Jun-2005
6
+ * Moved project to RubyForge.
7
+ * Added a CHANGES file.
8
+
9
+ == 0.1.0 - 26-Jan-2005
10
+ * Initial release
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
@@ -0,0 +1,10 @@
1
+ require "mkmf"
2
+ require "ftools"
3
+
4
+ File.copy("lib/io/extra.c",".")
5
+
6
+ have_func("closefrom")
7
+ have_func("fdwalk")
8
+ have_func("directio")
9
+
10
+ create_makefile("io/extra")
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
+ }
@@ -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
+