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.
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
+