io_splice 2.1.0 → 2.2.0

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/README CHANGED
@@ -23,6 +23,9 @@ buffer.
23
23
  * Fully-documented library API and
24
24
  {examples}[http://bogomips.org/ruby_io_splice/examples/]
25
25
 
26
+ * Adds helpful IO#pipe_size and IO#pipe_size= accessor methods for
27
+ resizing the pipe buffer in Linux 2.6.35 or later.
28
+
26
29
  == Install
27
30
 
28
31
  Operating system support for the splice(2), tee(2) and vmsplice(2)
@@ -10,6 +10,16 @@
10
10
  #include <sys/uio.h>
11
11
  #include <limits.h>
12
12
  #include <alloca.h>
13
+ #include <sys/utsname.h>
14
+
15
+ #ifndef F_LINUX_SPECIFIC_BASE
16
+ # define F_LINUX_SPECIFIC_BASE 1024
17
+ #endif
18
+
19
+ #ifndef F_GETPIPE_SZ
20
+ # define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
21
+ # define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
22
+ #endif
13
23
 
14
24
  #if ! HAVE_RB_IO_T
15
25
  # define rb_io_t OpenFile
@@ -361,9 +371,76 @@ static VALUE my_vmsplice(VALUE self, VALUE fd, VALUE data, VALUE flags)
361
371
  return LONG2NUM(rv);
362
372
  }
363
373
 
374
+ /*
375
+ * call-seq:
376
+ * reader, writer = IO.pipe
377
+ * reader.pipe_size => integer
378
+ *
379
+ * Returns the pipe capacity of the underlying pipe in bytes. The
380
+ * default capacity is 65536 bytes since Linux 2.6.11, and 4096 bytes
381
+ * in previous kernels.
382
+ *
383
+ * Since the pipe is a circular buffer in the same kernel, the size
384
+ * of the reader is exactly the same as the size of the writer.
385
+ *
386
+ * This method is only exposed on Linux 2.6.35 or later.
387
+ */
388
+ static VALUE pipe_size(VALUE self)
389
+ {
390
+ int size = fcntl(my_fileno(self), F_GETPIPE_SZ);
391
+
392
+ if (size < 0)
393
+ rb_sys_fail("fcntl(F_GETPIPE_SZ)");
394
+
395
+ return INT2NUM(size);
396
+ }
397
+
398
+ /*
399
+ * call-seq:
400
+ * reader, writer = IO.pipe
401
+ * reader.pipe_size = integer
402
+ *
403
+ * Sets and returns the pipe capacity of the underlying pipe in bytes.
404
+ *
405
+ * This MUST be a power-of-two, or Errno::EINVAL will be raised.
406
+ * Linux will silently increase this to be equal to the page size
407
+ * (4096 bytes on most architectures) if the specified value is
408
+ * less than the size of a page.
409
+ *
410
+ * For users without CAP_SYS_RESOURCE, this raises Errno::EPERM when
411
+ * attempting to specify a value greater than the value in
412
+ * /proc/sys/fs/pipe-max-size.
413
+ *
414
+ * Since the pipe is a circular buffer in the same kernel, the size
415
+ * of the reader is exactly the same as the size of the writer.
416
+ *
417
+ * Raises Errno::EBUSY if the assigned value is less than
418
+ * the currently filled portion of the pipe.
419
+ *
420
+ * This method is only exposed on Linux 2.6.35 or later.
421
+ */
422
+ static VALUE set_pipe_size(VALUE self, VALUE size)
423
+ {
424
+ int fd = my_fileno(self);
425
+ int bytes = NUM2INT(size);
426
+ int rv = fcntl(fd, F_SETPIPE_SZ, bytes);
427
+
428
+ if (rv < 0) {
429
+ if (errno == ENOMEM) {
430
+ rb_gc();
431
+ rv = fcntl(fd, F_SETPIPE_SZ, bytes);
432
+ }
433
+ if (rv < 0)
434
+ rb_sys_fail("fcntl(F_SETPIPE_SZ)");
435
+ }
436
+
437
+ return size;
438
+ }
439
+
364
440
  void Init_io_splice_ext(void)
365
441
  {
366
442
  VALUE mSplice = rb_define_module_under(rb_cIO, "Splice");
443
+ struct utsname utsname;
367
444
 
368
445
  rb_define_singleton_method(rb_cIO, "splice", my_splice, 6);
369
446
  rb_define_singleton_method(rb_cIO, "tee", my_tee, 4);
@@ -402,19 +479,35 @@ void Init_io_splice_ext(void)
402
479
  */
403
480
  rb_define_const(mSplice, "F_GIFT", UINT2NUM(SPLICE_F_GIFT));
404
481
 
405
- #ifdef F_GETPIPE_SZ
406
- /* :nodoc: */
407
- rb_define_const(mSplice, "F_GETPIPE_SZ", UINT2NUM(F_GETPIPE_SZ));
408
- #endif
409
- #ifdef F_SETPIPE_SZ
410
- /* :nodoc: */
411
- rb_define_const(mSplice, "F_SETPIPE_SZ", UINT2NUM(F_SETPIPE_SZ));
412
- #endif
413
-
414
482
  /*
415
483
  * The maximum size of an atomic write to a pipe
416
484
  * POSIX requires this to be at least 512 bytes.
417
485
  * Under Linux, this is 4096 bytes.
418
486
  */
419
487
  rb_define_const(mSplice, "PIPE_BUF", UINT2NUM(PIPE_BUF));
488
+
489
+ if (uname(&utsname) == -1)
490
+ rb_sys_fail("uname");
491
+
492
+ /* includes 2.6.35-rc[1-6] */
493
+ if (strcmp(utsname.release, "2.6.35") >= 0) {
494
+ rb_define_method(rb_cIO, "pipe_size", pipe_size, 0);
495
+ rb_define_method(rb_cIO, "pipe_size=", set_pipe_size, 1);
496
+
497
+ /*
498
+ * fcntl() command constant used to return the size of a pipe.
499
+ * This constant is only defined when running Linux 2.6.35
500
+ * or later. For convenience, use IO#pipe_size instead.
501
+ */
502
+ rb_define_const(mSplice, "F_GETPIPE_SZ",
503
+ UINT2NUM(F_GETPIPE_SZ));
504
+
505
+ /*
506
+ * fcntl() command constant used to set the size of a pipe.
507
+ * This constant is only defined when running Linux 2.6.35
508
+ * or later. For convenience, use IO#pipe_size= instead.
509
+ */
510
+ rb_define_const(mSplice, "F_SETPIPE_SZ",
511
+ UINT2NUM(F_SETPIPE_SZ));
512
+ }
420
513
  }
data/lib/io/splice.rb CHANGED
@@ -5,8 +5,8 @@ class IO
5
5
 
6
6
  module Splice
7
7
 
8
- # the version of IO::Splice, currently 2.1.0
9
- VERSION = '2.1.0'
8
+ # the version of IO::Splice, currently 2.2.0
9
+ VERSION = '2.2.0'
10
10
 
11
11
  # The maximum default capacity of the pipe in bytes.
12
12
  # Under stock Linux, this is 65536 bytes as of 2.6.11, and 4096 before
@@ -251,7 +251,7 @@ class Test_IO_Splice < Test::Unit::TestCase
251
251
  tmp = []
252
252
  begin
253
253
  sleep 0.005
254
- tmp << rd.readpartial(8192, buf)
254
+ tmp << rd.readpartial(8192)
255
255
  rescue EOFError
256
256
  break
257
257
  end while true
@@ -393,4 +393,19 @@ class Test_IO_Splice < Test::Unit::TestCase
393
393
  assert_equal 'hello world', a.read
394
394
  end
395
395
 
396
+ def test_pipe_size
397
+ r, w = IO.pipe
398
+ assert Integer, r.pipe_size
399
+ assert(r.pipe_size >= 512)
400
+ assert_nothing_raised { w.pipe_size = 8192 }
401
+ assert 8192, r.pipe_size
402
+
403
+ w.write('*' * 4097)
404
+ assert_raises(Errno::EBUSY) { r.pipe_size = 4096 }
405
+
406
+ pipe_max_size = File.read("/proc/sys/fs/pipe-max-size").to_i
407
+ assert_nothing_raised { r.pipe_size = pipe_max_size }
408
+ assert_raises(Errno::EPERM) { r.pipe_size = pipe_max_size * 2 }
409
+ end if IO.method_defined?(:pipe_size)
410
+
396
411
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io_splice
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ hash: 7
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 2
9
+ - 0
10
+ version: 2.2.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - io_splice hackers
@@ -9,7 +15,7 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-06-06 00:00:00 +00:00
18
+ date: 2010-08-02 00:00:00 +00:00
13
19
  default_executable:
14
20
  dependencies: []
15
21
 
@@ -64,21 +70,27 @@ rdoc_options:
64
70
  require_paths:
65
71
  - lib
66
72
  required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
67
74
  requirements:
68
75
  - - ">="
69
76
  - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
70
80
  version: "0"
71
- version:
72
81
  required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
73
83
  requirements:
74
84
  - - ">="
75
85
  - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
76
89
  version: "0"
77
- version:
78
90
  requirements: []
79
91
 
80
92
  rubyforge_project: qrp
81
- rubygems_version: 1.3.5
93
+ rubygems_version: 1.3.7
82
94
  signing_key:
83
95
  specification_version: 3
84
96
  summary: zero-copy pipe I/O for Linux and Ruby