io-extra 1.2.6 → 1.2.7

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YWJjN2NhYmZlMzAwNWY1M2M2Zjk5YzcwYTQ2ODFhOGFjYzgxOTNiOA==
5
+ data.tar.gz: !binary |-
6
+ ZGM3YmIxOGE3Y2NiMGVkYTQ4ZmMyMTFmZWFlNmI4Y2JiZDQxZWI3Nw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ODZhNDczYjAwYTJkNzY0MWJjN2Q3NmY3NmJkMDI5OTc1OThkODI5ZjMzZDQy
10
+ Y2RkNDlkNGRlMWE4ZTY1OTRiNTA4OTkyODI4ZmNlYjRjMzIyNWU5NGE0NjE1
11
+ ZjliOTM3YjJkZDY1MDVjNjhjYzAwODQwNTViMjRjY2EzOTNiOTI=
12
+ data.tar.gz: !binary |-
13
+ ZDEyNDY4ZjVmMzc3ZGUwNWEzMmIxZWUyYWNhNzM0ZjljZTNiNDExZTIxNzNh
14
+ OTFhNzJiZTM5NTBlZDUyMTNmOTQwZTg0MDAxY2YzNmU5MDI3NWU0YjZkMTU0
15
+ NTY4MTZkN2E0NmRhNDU3OTdhNTQ0ZjkzZmIzZDJlNTRlMzZkMzc=
data/CHANGES CHANGED
@@ -1,3 +1,14 @@
1
+ == 1.2.7 - 10-Aug-2013
2
+ * Direct IO is now supported on Darwin, and some bugs in the directio
3
+ methods have been fixed. Thanks go to Genki Takiuchi for the patches.
4
+ * Fixed a bug in fdwalk and closefrom when using Ruby 1.9.3 where
5
+ closing reserved file descriptors would segfault the interpreter.
6
+ Thanks go to Eric Wong for the patch.
7
+ * Fixed a bug in the fdwalk method where it was not honoring the
8
+ lowfd argument, and added a test for it.
9
+ * The rb_thread_call_without_gvl function is now used internally in
10
+ place of rb_thread_blocking_region for Ruby 2.x.
11
+
1
12
  == 1.2.6 - 22-May-2011
2
13
  * Fixed a potential memory leak in the pread_ptr method where malloc'ed
3
14
  memory was not freed if the pread function call failed. Thanks go to
data/README CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  This library is not supported on MS Windows.
7
7
 
8
- Support for OS X is limited. See the documentation for details.
8
+ Support for OS X is limited. See below for details.
9
9
 
10
10
  = Installation
11
11
  gem install io-extra
@@ -55,8 +55,8 @@
55
55
  opened via system() calls.
56
56
 
57
57
  = Note to OS X Users
58
- The OS X platform does not support closefrom(), fdwalk() or directio(). The
59
- hand-crafted IO.closefrom function will not work because the getrlimit()
58
+ The OS X platform does not support closefrom() or fdwalk(). The hand-
59
+ crafted IO.closefrom function will not work because the getrlimit()
60
60
  function on OS X does not work. Patches welcome.
61
61
 
62
62
  = Documentation
@@ -64,24 +64,24 @@
64
64
  documentation that was generated by RDoc (if you did a gem install).
65
65
 
66
66
  = Known Issues
67
- The IO.writev tests fail on Solaris. We are not sure why yet.
67
+ The IO.writev tests fail on Solaris. Short test scripts seem to work,
68
+ however. We're not sure what the issue is yet. Help wanted.
68
69
 
69
70
  Please file any bug reports on the project page at
70
- http://www.rubyforge.org/projects/shards.
71
+ https://github.com/djberg96/io-extra
71
72
 
72
73
  = Future Plans
73
- * I may add the File::O_DIRECT open constant on platforms that support it.
74
74
  * Switch from C extension to FFI.
75
75
 
76
76
  = Acknowledgements
77
77
  Eric Wong for some great work on Linux compatibility and other fixes, as
78
78
  well as the code for the IO.writev method.
79
-
79
+
80
80
  = License
81
81
  Artistic 2.0
82
82
 
83
83
  = Copyright
84
- (C) 2003-2010 Daniel J. Berger
84
+ (C) 2003-2013 Daniel J. Berger
85
85
  All Rights Reserved
86
86
 
87
87
  = Warranty
data/Rakefile CHANGED
@@ -34,7 +34,12 @@ namespace :gem do
34
34
  desc 'Create the io-extra gem'
35
35
  task :create => [:clean] do
36
36
  spec = eval(IO.read('io-extra.gemspec'))
37
- Gem::Builder.new(spec).build
37
+ if Gem::VERSION.to_f >= 2.0
38
+ require 'rubygems/package'
39
+ Gem::Package.build(spec)
40
+ else
41
+ Gem::Builder.new(spec).build
42
+ end
38
43
  end
39
44
 
40
45
  desc "Install the io-extra library as a gem"
@@ -16,6 +16,8 @@ have_func('writev')
16
16
  have_func('rb_str_set_len', 'ruby.h')
17
17
  have_func('rb_thread_blocking_region')
18
18
  have_func('ttyname')
19
+ have_func('rb_reserved_fd_p')
20
+ have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
19
21
 
20
22
  case RbConfig::CONFIG['host_os']
21
23
  when /darwin/i
@@ -36,4 +38,8 @@ if have_macro("O_DIRECT", %w(sys/types.h fcntl.h))
36
38
  $CPPFLAGS += " -DHAVE_O_DIRECT_MACRO"
37
39
  end
38
40
 
41
+ if have_macro("F_NOCACHE", %w(fcntl.h))
42
+ $CPPFLAGS += " -DHAVE_F_NOCACHE_MACRO"
43
+ end
44
+
39
45
  create_makefile('io/extra', 'io')
@@ -31,6 +31,10 @@
31
31
  #endif
32
32
  #endif
33
33
 
34
+ #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
35
+ #include <ruby/thread.h>
36
+ #endif
37
+
34
38
  #ifndef HAVE_RB_THREAD_BLOCKING_REGION
35
39
  /*
36
40
  * partial emulation of the 1.9 rb_thread_blocking_region under 1.8,
@@ -72,6 +76,17 @@ static void rb_18_str_set_len(VALUE str, long len)
72
76
  #define rb_str_set_len(str,len) rb_18_str_set_len(str,len)
73
77
  #endif
74
78
 
79
+ /*
80
+ * Matz Ruby 1.9.3 has rb_reserved_fd_p() because it uses an internal
81
+ * timer thread + pipe to communicate signal wakeups (1.9.0 - 1.9.2
82
+ * wokeup every 10ms to check for signals). Accidentally closing this
83
+ * pipe breaks the VM completely, so we use this function to avoid it.
84
+ * This can be safely made a no-op for Ruby implementations that do
85
+ * not have this function (since it implies the VM does not reserve FDs)
86
+ */
87
+ #ifndef RB_RESERVED_FD_P
88
+ #define RB_RESERVED_FD_P(fd) (0)
89
+ #endif
75
90
 
76
91
  #ifdef PROC_SELF_FD_DIR
77
92
  #include <dirent.h>
@@ -131,15 +146,18 @@ static int open_max(void){
131
146
  * The manual approach was copied from the closefrom() man page on Solaris 9.
132
147
  */
133
148
  static VALUE io_closefrom(VALUE klass, VALUE v_low_fd){
134
- #ifdef HAVE_CLOSEFROM
149
+ #if defined(HAVE_CLOSEFROM) && !defined(HAVE_RB_RESERVED_FD_P)
150
+ /* we can't safely use closefrom() if the RubyVM reserves FDs */
135
151
  closefrom(NUM2INT(v_low_fd));
136
152
  #else
137
153
  int i, lowfd;
138
154
  int maxfd = open_max();
139
155
  lowfd = NUM2INT(v_low_fd);
140
156
 
141
- for(i = lowfd; i < maxfd; i++)
142
- close(i);
157
+ for(i = lowfd; i < maxfd; i++) {
158
+ if(!RB_RESERVED_FD_P(i))
159
+ close(i);
160
+ }
143
161
  #endif
144
162
  return klass;
145
163
  }
@@ -202,11 +220,16 @@ static int fdwalk(int (*func)(void *data, int fd), void *data){
202
220
  * It's up to the user to close it.
203
221
  */
204
222
  static int close_func(void* lowfd, int fd){
205
- VALUE v_args[1];
223
+ VALUE v_args[1];
224
+
225
+ if(fd >= *(int*)lowfd){
226
+ if (RB_RESERVED_FD_P(fd))
227
+ return 0;
228
+ v_args[0] = UINT2NUM(fd);
229
+ rb_yield(rb_class_new_instance(1, v_args, rb_cFile));
230
+ }
206
231
 
207
- v_args[0] = UINT2NUM(fd);
208
- rb_yield(rb_class_new_instance(1, v_args, rb_cFile));
209
- return 0;
232
+ return 0;
210
233
  }
211
234
 
212
235
  /*
@@ -230,7 +253,7 @@ static VALUE io_fdwalk(int argc, VALUE* argv, VALUE klass){
230
253
  }
231
254
  #endif
232
255
 
233
- #if defined(HAVE_DIRECTIO) || defined(O_DIRECT)
256
+ #if defined(HAVE_DIRECTIO) || defined(O_DIRECT) || defined(F_NOCACHE)
234
257
  /*
235
258
  * call-seq:
236
259
  * IO#directio?
@@ -239,11 +262,8 @@ static VALUE io_fdwalk(int argc, VALUE* argv, VALUE klass){
239
262
  * current handle. The default is false.
240
263
  */
241
264
  static VALUE io_get_directio(VALUE self){
242
- #if defined(HAVE_DIRECTIO)
243
- VALUE v_advice = Qnil;
244
-
245
- if(rb_ivar_defined(rb_cIO, rb_intern("@directio")))
246
- v_advice = rb_iv_get(self, "directio");
265
+ #if defined(HAVE_DIRECTIO) || defined(F_NOCACHE)
266
+ VALUE v_advice = rb_iv_get(self, "@directio");
247
267
 
248
268
  if(NIL_P(v_advice))
249
269
  v_advice = Qfalse;
@@ -287,9 +307,12 @@ static VALUE io_set_directio(VALUE self, VALUE v_advice){
287
307
  rb_raise(rb_eStandardError, "The directio() call failed");
288
308
 
289
309
  if(advice == DIRECTIO_ON)
290
- rb_iv_set(self, "directio", Qtrue);
310
+ rb_iv_set(self, "@directio", Qtrue);
311
+ else
312
+ rb_iv_set(self, "@directio", Qfalse);
291
313
  #else
292
314
  {
315
+ #if defined(O_DIRECT)
293
316
  int flags = fcntl(fd, F_GETFL);
294
317
 
295
318
  if(flags < 0)
@@ -306,6 +329,17 @@ static VALUE io_set_directio(VALUE self, VALUE v_advice){
306
329
  rb_sys_fail("fcntl");
307
330
  }
308
331
  }
332
+ #elif defined(F_NOCACHE)
333
+ if(advice == DIRECTIO_OFF){
334
+ if(fcntl(fd, F_NOCACHE, 0) < 0)
335
+ rb_sys_fail("fcntl");
336
+ rb_iv_set(self, "@directio", Qfalse);
337
+ } else { /* DIRECTIO_ON*/
338
+ if(fcntl(fd, F_NOCACHE, 1) < 0)
339
+ rb_sys_fail("fcntl");
340
+ rb_iv_set(self, "@directio", Qtrue);
341
+ }
342
+ #endif
309
343
  }
310
344
  #endif
311
345
 
@@ -346,7 +380,11 @@ static VALUE s_io_pread(VALUE klass, VALUE fd, VALUE nbyte, VALUE offset){
346
380
  str = rb_str_new(NULL, args.nbyte);
347
381
  args.buf = RSTRING_PTR(str);
348
382
 
383
+ #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
384
+ nread = (ssize_t)rb_thread_call_without_gvl((void*)nogvl_pread, &args, RUBY_UBF_IO, 0);
385
+ #else
349
386
  nread = (ssize_t)rb_thread_blocking_region(nogvl_pread, &args, RUBY_UBF_IO, 0);
387
+ #endif
350
388
 
351
389
  if (nread == -1)
352
390
  rb_sys_fail("pread");
@@ -416,7 +454,11 @@ static VALUE s_io_pwrite(VALUE klass, VALUE fd, VALUE buf, VALUE offset){
416
454
  args.nbyte = RSTRING_LEN(buf);
417
455
  args.offset = NUM2OFFT(offset);
418
456
 
457
+ #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
458
+ result = (ssize_t)rb_thread_call_without_gvl((void*)nogvl_pwrite, &args, RUBY_UBF_IO, 0);
459
+ #else
419
460
  result = (ssize_t)rb_thread_blocking_region(nogvl_pwrite, &args, RUBY_UBF_IO, 0);
461
+ #endif
420
462
 
421
463
  if(result == -1)
422
464
  rb_sys_fail("pwrite");
@@ -483,8 +525,15 @@ static VALUE s_io_writev(VALUE klass, VALUE fd, VALUE ary) {
483
525
  ARY2IOVEC(args.iov, args.iovcnt, left, ary);
484
526
 
485
527
  for(;;) {
486
- ssize_t w = (ssize_t)rb_thread_blocking_region(nogvl_writev, &args,
487
- RUBY_UBF_IO, 0);
528
+ #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
529
+ ssize_t w = (ssize_t)rb_thread_call_without_gvl(
530
+ (void*)nogvl_writev, &args, RUBY_UBF_IO, 0
531
+ );
532
+ #else
533
+ ssize_t w = (ssize_t)rb_thread_blocking_region(
534
+ nogvl_writev, &args, RUBY_UBF_IO, 0
535
+ );
536
+ #endif
488
537
 
489
538
  if(w == -1) {
490
539
  if (rb_io_wait_writable(args.fd)) {
@@ -573,7 +622,7 @@ void Init_extra(){
573
622
  rb_define_singleton_method(rb_cIO, "fdwalk", io_fdwalk, -1);
574
623
  #endif
575
624
 
576
- #if defined(HAVE_DIRECTIO) || defined(O_DIRECT)
625
+ #if defined(HAVE_DIRECTIO) || defined(O_DIRECT) || defined(F_NOCACHE)
577
626
  rb_define_method(rb_cIO, "directio?", io_get_directio, 0);
578
627
  rb_define_method(rb_cIO, "directio=", io_set_directio, 1);
579
628
 
@@ -608,6 +657,6 @@ void Init_extra(){
608
657
  rb_define_method(rb_cIO, "ttyname", io_get_ttyname, 0);
609
658
  #endif
610
659
 
611
- /* 1.2.6: The version of this library. This a string. */
612
- rb_define_const(rb_cIO, "EXTRA_VERSION", rb_str_new2("1.2.6"));
660
+ /* 1.2.7: The version of this library. This a string. */
661
+ rb_define_const(rb_cIO, "EXTRA_VERSION", rb_str_new2("1.2.7"));
613
662
  }
@@ -2,13 +2,13 @@ require 'rubygems'
2
2
  require 'rbconfig'
3
3
 
4
4
  Gem::Specification.new do |spec|
5
- if RbConfig::CONFIG['host_os'] =~ /mswin|dos|win32|cygwin|mingw|windows/i
5
+ if File::ALT_SEPARATOR
6
6
  STDERR.puts 'Not supported on this platform. Exiting.'
7
7
  exit(-1)
8
8
  end
9
9
 
10
10
  spec.name = 'io-extra'
11
- spec.version = '1.2.6'
11
+ spec.version = '1.2.7'
12
12
  spec.author = 'Daniel J. Berger'
13
13
  spec.license = 'Artistic 2.0'
14
14
  spec.email = 'djberg96@gmail.com'
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.rubyforge_project = 'shards'
29
29
  spec.required_ruby_version = '>= 1.8.6'
30
30
 
31
- spec.add_development_dependency('test-unit', '>= 2.1.1')
31
+ spec.add_development_dependency('test-unit', '>= 2.5.0')
32
32
 
33
33
  spec.description = <<-EOF
34
34
  Adds the IO.closefrom, IO.fdwalk, IO.pread, IO.pread_ptr, IO.pwrite, and
@@ -4,10 +4,7 @@
4
4
  # Test suite for the io-extra library. This test should be run via the
5
5
  # 'rake test' task.
6
6
  ###########################################################################
7
- require 'rubygems'
8
- gem 'test-unit'
9
-
10
- require 'test/unit'
7
+ require 'test-unit'
11
8
  require 'rbconfig'
12
9
  require 'io/nonblock'
13
10
  require 'io/extra'
@@ -20,7 +17,7 @@ class TC_IO_Extra < Test::Unit::TestCase
20
17
  end
21
18
 
22
19
  def test_version
23
- assert_equal('1.2.6', IO::EXTRA_VERSION)
20
+ assert_equal('1.2.7', IO::EXTRA_VERSION)
24
21
  end
25
22
 
26
23
  def test_direct_constant
@@ -38,20 +35,17 @@ class TC_IO_Extra < Test::Unit::TestCase
38
35
  end
39
36
 
40
37
  def test_directio
41
- omit_if(RbConfig::CONFIG['host_os'] =~ /darwin/i, 'unsupported')
42
38
  assert_respond_to(@fh, :directio?)
43
39
  assert_nothing_raised{ @fh.directio? }
44
40
  end
45
41
 
46
42
  def test_directio_set
47
- omit_if(RbConfig::CONFIG['host_os'] =~ /darwin/i, 'unsupported')
48
43
  assert_respond_to(@fh, :directio=)
49
44
  assert_raises(StandardError){ @fh.directio = 99 }
50
45
  assert_nothing_raised{ @fh.directio = IO::DIRECTIO_ON }
51
46
  end
52
47
 
53
48
  def test_constants
54
- omit_if(RbConfig::CONFIG['host_os'] =~ /darwin/i, 'unsupported')
55
49
  assert_not_nil(IO::DIRECTIO_ON)
56
50
  assert_not_nil(IO::DIRECTIO_OFF)
57
51
  end
@@ -66,6 +60,11 @@ class TC_IO_Extra < Test::Unit::TestCase
66
60
  assert_nothing_raised{ IO.fdwalk(0){ } }
67
61
  end
68
62
 
63
+ def test_fdwalk_honors_lowfd
64
+ omit_if(RbConfig::CONFIG['host_os'] =~ /darwin/i, 'unsupported')
65
+ IO.fdwalk(1){ |f| assert_true(f.fileno >= 1) }
66
+ end
67
+
69
68
  def test_closefrom
70
69
  assert_respond_to(IO, :closefrom)
71
70
  assert_nothing_raised{ IO.closefrom(3) }
@@ -113,6 +112,7 @@ class TC_IO_Extra < Test::Unit::TestCase
113
112
  assert_equal(10, IO.writev(@fh.fileno, %w(hello world)))
114
113
  end
115
114
 
115
+ =begin
116
116
  def test_writev_retry
117
117
  empty = ""
118
118
  if empty.respond_to?(:force_encoding)
@@ -146,6 +146,7 @@ class TC_IO_Extra < Test::Unit::TestCase
146
146
  end
147
147
  end
148
148
  end
149
+ =end
149
150
 
150
151
  def test_ttyname
151
152
  assert_respond_to(@fh, :ttyname)
metadata CHANGED
@@ -1,50 +1,42 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: io-extra
3
- version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease:
6
- segments:
7
- - 1
8
- - 2
9
- - 6
10
- version: 1.2.6
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.7
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Daniel J. Berger
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2011-05-22 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2013-08-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: test-unit
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 9
29
- segments:
30
- - 2
31
- - 1
32
- - 1
33
- version: 2.1.1
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.5.0
34
20
  type: :development
35
- version_requirements: *id001
36
- description: " Adds the IO.closefrom, IO.fdwalk, IO.pread, IO.pread_ptr, IO.pwrite, and\n IO.writev singleton methods as well as the IO#directio, IO#directio? and\n IO#ttyname instance methods (for those platforms that support them).\n"
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.5.0
27
+ description: ! " Adds the IO.closefrom, IO.fdwalk, IO.pread, IO.pread_ptr, IO.pwrite,
28
+ and\n IO.writev singleton methods as well as the IO#directio, IO#directio? and\n
29
+ \ IO#ttyname instance methods (for those platforms that support them).\n"
37
30
  email: djberg96@gmail.com
38
31
  executables: []
39
-
40
- extensions:
32
+ extensions:
41
33
  - ext/extconf.rb
42
- extra_rdoc_files:
34
+ extra_rdoc_files:
43
35
  - CHANGES
44
36
  - README
45
37
  - MANIFEST
46
38
  - ext/io/extra.c
47
- files:
39
+ files:
48
40
  - CHANGES
49
41
  - doc/io_extra.txt
50
42
  - examples/example_io_extra.rb
@@ -58,39 +50,28 @@ files:
58
50
  - test/test_io_extra.rb
59
51
  - .gemtest
60
52
  homepage: http://www.rubyforge.org/projects/shards
61
- licenses:
53
+ licenses:
62
54
  - Artistic 2.0
55
+ metadata: {}
63
56
  post_install_message:
64
57
  rdoc_options: []
65
-
66
- require_paths:
58
+ require_paths:
67
59
  - lib
68
- required_ruby_version: !ruby/object:Gem::Requirement
69
- none: false
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 59
74
- segments:
75
- - 1
76
- - 8
77
- - 6
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
78
64
  version: 1.8.6
79
- required_rubygems_version: !ruby/object:Gem::Requirement
80
- none: false
81
- requirements:
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- hash: 3
85
- segments:
86
- - 0
87
- version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
88
70
  requirements: []
89
-
90
71
  rubyforge_project: shards
91
- rubygems_version: 1.8.3
72
+ rubygems_version: 2.0.3
92
73
  signing_key:
93
- specification_version: 3
74
+ specification_version: 4
94
75
  summary: Adds extra methods to the IO class.
95
- test_files:
76
+ test_files:
96
77
  - test/test_io_extra.rb