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 +3 -0
- data/ext/io_splice/io_splice_ext.c +102 -9
- data/lib/io/splice.rb +2 -2
- data/test/test_io_splice.rb +16 -1
- metadata +17 -5
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.
|
9
|
-
VERSION = '2.
|
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
|
data/test/test_io_splice.rb
CHANGED
@@ -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
|
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
|
-
|
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-
|
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.
|
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
|