Class: IO
- Inherits:
-
Object
- Object
- IO
- Defined in:
- (unknown)
Defined Under Namespace
Modules: Splice
Class Method Summary collapse
-
.splice(*args) ⇒ Object
Splice
len
bytes from/to a pipe. -
.tee(*args) ⇒ Object
Copies up to
len
bytes of data fromio_in
toio_out
. -
.trysplice(*args) ⇒ Object
Exactly like IO.splice, except
:EAGAIN
is returned when either the read or write end would block instead of raising Errno::EAGAIN. -
.trytee(*args) ⇒ Object
Exactly like IO.tee, except
:EAGAIN
is returned when either the read or write end would block instead of raising Errno::EAGAIN. -
.vmsplice(*args) ⇒ Object
Transfers an array of strings into the pipe descriptor given by io.
Instance Method Summary collapse
-
#pipe_size ⇒ Object
Returns the pipe capacity of the underlying pipe in bytes.
-
#pipe_size=(size) ⇒ Object
Sets and returns the pipe capacity of the underlying pipe in bytes.
Class Method Details
.splice(io_in, off_in, io_out, off_out, len) ⇒ Integer .splice(io_in, off_in, io_out, off_out, len, flags) ⇒ Integer
Splice len
bytes from/to a pipe. Either io_in
or io_out
MUST be a pipe. io_in
and io_out
may BOTH be pipes as of Linux 2.6.31 or later.
off_in
and off_out
if non-nil may be used to specify an offset for the non-pipe file descriptor.
flags
defaults to zero if unspecified. flags
may be a bitmask of the following flags:
-
IO::Splice::F_MOVE
-
IO::Splice::F_NONBLOCK
-
IO::Splice::F_MORE
-
IO::Splice::WAITALL
Returns the number of bytes spliced. Raises EOFError when io_in
has reached end of file. Raises Errno::EAGAIN if the IO::Splice::F_NONBLOCK flag is set and the pipe has no data to read from or space to write to. May also raise Errno::EAGAIN if the non-pipe descriptor has no data to read from or space to write to.
As splice never exposes buffers to userspace, it will not take into account userspace buffering done by Ruby or stdio. It is also not subject to encoding/decoding filters under Ruby 1.9.
Consider using IO.trysplice if you are using non-blocking I/O on both descriptors as it avoids the cost of raising common Errno::EAGAIN exceptions.
See manpage for full documentation: kernel.org/doc/man-pages/online/pages/man2/splice.2.html
227 228 229 230 231 232 233 234 235 236 |
# File 'ext/io_splice/io_splice_ext.c', line 227
static VALUE my_splice(int argc, VALUE *argv, VALUE self)
{
ssize_t n = do_splice(argc, argv, 0);
if (n == 0)
rb_eof_error();
if (n == -1)
rb_sys_fail("splice");
return SSIZET2NUM(n);
}
|
.tee(io_in, io_out, len) ⇒ Integer .tee(io_in, io_out, len, flags) ⇒ Integer
Copies up to len
bytes of data from io_in
to io_out
. io_in
and io_out
must both refer to pipe descriptors. io_in
and io_out
may not be endpoints of the same pipe.
flags
may be zero (the default) or a combination of:
-
IO::Splice::F_NONBLOCK
-
IO::Splice::WAITALL
Other IO::Splice flags are currently unimplemented or have no effect.
Returns the number of bytes duplicated if successful. Raises EOFError when io_in
is closed and emptied. Raises Errno::EAGAIN when io_in
is empty and/or io_out
is full and flags
contains IO::Splice::F_NONBLOCK
Consider using IO.trytee if you are using IO::Splice::F_NONBLOCK as it avoids the cost of raising common Errno::EAGAIN exceptions.
See manpage for full documentation: kernel.org/doc/man-pages/online/pages/man2/tee.2.html
351 352 353 354 355 356 357 358 359 360 361 |
# File 'ext/io_splice/io_splice_ext.c', line 351
static VALUE my_tee(int argc, VALUE *argv, VALUE self)
{
ssize_t n = do_tee(argc, argv, 0);
if (n == 0)
rb_eof_error();
if (n == -1)
rb_sys_fail("tee");
return SSIZET2NUM(n);
}
|
.trysplice(io_in, off_in, io_out, off_out, len) ⇒ Integer .trysplice(io_in, off_in, io_out, off_out, len, flags) ⇒ Integer
Exactly like IO.splice, except :EAGAIN
is returned when either the read or write end would block instead of raising Errno::EAGAIN.
IO::Splice::F_NONBLOCK is always passed for the pipe descriptor, but this can still block if the non-pipe descriptor is blocking.
See IO.splice documentation for more details.
251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'ext/io_splice/io_splice_ext.c', line 251
static VALUE trysplice(int argc, VALUE *argv, VALUE self)
{
ssize_t n = do_splice(argc, argv, SPLICE_F_NONBLOCK);
if (n == 0)
return Qnil;
if (n == -1) {
if (errno == EAGAIN)
return sym_EAGAIN;
rb_sys_fail("splice");
}
return SSIZET2NUM(n);
}
|
.trytee(io_in, io_out, len) ⇒ Integer .trytee(io_in, io_out, len, flags) ⇒ Integer
Exactly like IO.tee, except :EAGAIN
is returned when either the read or write end would block instead of raising Errno::EAGAIN.
IO::Splice::F_NONBLOCK is always passed for the pipe descriptor, but this can still block if the non-pipe descriptor is blocking.
See IO.tee documentation for more details.
376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
# File 'ext/io_splice/io_splice_ext.c', line 376
static VALUE trytee(int argc, VALUE *argv, VALUE self)
{
ssize_t n = do_tee(argc, argv, SPLICE_F_NONBLOCK);
if (n == 0)
return Qnil;
if (n == -1) {
if (errno == EAGAIN)
return sym_EAGAIN;
rb_sys_fail("tee");
}
return SSIZET2NUM(n);
}
|
.vmsplice(io, string_array) ⇒ Integer .vmsplice(io, string_array, flags) ⇒ Integer .vmsplice(io, string) ⇒ Integer .vmsplice(io, string, flags) ⇒ Integer
Transfers an array of strings into the pipe descriptor given by io. io
must be the writable end of a pipe.
This may allow the kernel to avoid data copies in some cases. but is (probably) of limited usefulness in Ruby. If you have use cases or ideas for making this more useful for Ruby users, please tell us at [email protected]!
Also consider the “sendfile” RubyGem or IO.copy_stream in Ruby 1.9 if you want to do zero-copy file transfers to pipes or sockets. As of Linux 2.6.33, sendfile(2) can copy to any output descriptor, not just sockets.
See manpage for full documentation: kernel.org/doc/man-pages/online/pages/man2/vmsplice.2.html
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
# File 'ext/io_splice/io_splice_ext.c', line 479
static VALUE my_vmsplice(int argc, VALUE * argv, VALUE self)
{
ssize_t rv = 0;
ssize_t left;
struct vmsplice_args a;
VALUE io, data, flags;
rb_scan_args(argc, argv, "21", &io, &data, &flags);
switch (TYPE(data)) {
case T_STRING: {
struct iovec iov;
iov.iov_base = RSTRING_PTR(data);
iov.iov_len = (size_t)(left = (ssize_t)RSTRING_LEN(data));
a.iov = &iov;
a.nr_segs = 1;
}
break;
case T_ARRAY:
ARY2IOVEC(a.iov, a.nr_segs, left, data);
break;
default:
rb_raise(rb_eTypeError, "wrong argument type %s "
"(expected a String or Array of strings)",
rb_obj_classname(data));
}
a.fd = my_fileno(io);
a.flags = NIL_P(flags) ? 0 : NUM2UINT(flags);
for (;;) {
ssize_t n = (ssize_t)io_run(nogvl_vmsplice, &a);
if (n == -1) {
if (errno == EAGAIN) {
if (a.flags & SPLICE_F_NONBLOCK) {
rb_sys_fail("vmsplice");
} else {
a.fd = check_fileno(io);
if (rb_io_wait_writable(a.fd))
continue;
}
/* fall through on error */
}
/*
* unlikely to hit this case, return the
* already written bytes, we'll let the next
* write (or close) fail instead
*/
if (rv > 0)
break;
if (errno == EINTR) {
a.fd = check_fileno(io);
continue;
}
rb_sys_fail("vmsplice");
}
rv += n;
left -= n;
if (left == 0)
break;
advance_vmsplice_args(&a, n);
}
return SSIZET2NUM(rv);
}
|
Instance Method Details
#reader ⇒ Object #pipe_size ⇒ Integer
Returns the pipe capacity of the underlying pipe in bytes. The default capacity is 65536 bytes since Linux 2.6.11, and 4096 bytes in previous kernels.
Since the pipe is a circular buffer in the same kernel, the size of the reader is exactly the same as the size of the writer.
This method is only exposed on Linux 2.6.35 or later.
561 562 563 564 565 566 567 568 569 |
# File 'ext/io_splice/io_splice_ext.c', line 561
static VALUE pipe_size(VALUE self)
{
int size = fcntl(my_fileno(self), F_GETPIPE_SZ);
if (size < 0)
rb_sys_fail("fcntl(F_GETPIPE_SZ)");
return INT2NUM(size);
}
|
#reader ⇒ Object #pipe_size=(integer) ⇒ Object
Sets and returns the pipe capacity of the underlying pipe in bytes.
This MUST be a power-of-two, or Errno::EINVAL will be raised. Linux will silently increase this to be equal to the page size (4096 bytes on most architectures) if the specified value is less than the size of a page.
For users without CAP_SYS_RESOURCE, this raises Errno::EPERM when attempting to specify a value greater than the value in /proc/sys/fs/pipe-max-size.
Since the pipe is a circular buffer in the same kernel, the size of the reader is exactly the same as the size of the writer.
Raises Errno::EBUSY if the assigned value is less than the currently filled portion of the pipe.
This method is only exposed on Linux 2.6.35 or later.
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 |
# File 'ext/io_splice/io_splice_ext.c', line 595
static VALUE set_pipe_size(VALUE self, VALUE size)
{
int fd = my_fileno(self);
int bytes = NUM2INT(size);
int rv = fcntl(fd, F_SETPIPE_SZ, bytes);
if (rv < 0) {
if (errno == ENOMEM) {
rb_gc();
rv = fcntl(fd, F_SETPIPE_SZ, bytes);
}
if (rv < 0)
rb_sys_fail("fcntl(F_SETPIPE_SZ)");
}
return size;
}
|