io_splice 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|