13 #include <sys/utsname.h>
15 static VALUE sym_EAGAIN
;
17 #ifndef F_LINUX_SPECIFIC_BASE
18 # define F_LINUX_SPECIFIC_BASE 1024
22 # define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
23 # define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
27 # define rb_io_t OpenFile
31 # define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
33 # if !HAVE_RB_IO_T || (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
34 # define FPTR_TO_FD(fptr) fileno(fptr->f)
36 # define FPTR_TO_FD(fptr) fptr->fd
40 static int my_fileno(VALUE io
)
46 case T_FIXNUM
: return NUM2INT(io
);
48 GetOpenFile(io
, fptr
);
49 return FPTR_TO_FD(fptr
);
52 io
= rb_convert_type(io
, T_FILE
, "IO", "to_io");
57 #ifndef HAVE_RB_THREAD_BLOCKING_REGION
58 /* partial emulation of the 1.9 rb_thread_blocking_region under 1.8 */
60 # define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
61 typedef void rb_unblock_function_t(void *);
62 typedef VALUE
rb_blocking_function_t(void *);
64 rb_thread_blocking_region(
65 rb_blocking_function_t
*fn
, void *data1
,
66 rb_unblock_function_t
*ubf
, void *data2
)
70 assert(RUBY_UBF_IO
== ubf
&& "RUBY_UBF_IO required for emulation");
78 #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
81 # define RSTRING_PTR(s) (RSTRING(s)->ptr)
84 # define RSTRING_LEN(s) (RSTRING(s)->len)
87 # define RARRAY_PTR(s) (RARRAY(s)->ptr)
90 # define RARRAY_LEN(s) (RARRAY(s)->len)
93 static VALUE
io_run(rb_blocking_function_t
*fn
, void *data
)
95 return rb_thread_blocking_region(fn
, data
, RUBY_UBF_IO
, 0);
99 * Releases GVL only iff blocking I/O is used.
100 * Only use this if all file descriptors in data are pipes.
101 * We'll trust programmers who use non-blocking I/O explicitly to
102 * want the fastest possible performance without resorting to threads,
103 * so releasing and them immediately reacquiring the GVL would be
106 static VALUE
nb_io_run(rb_blocking_function_t
*fn
, void *data
, unsigned flags
)
108 if (flags
& SPLICE_F_NONBLOCK
)
110 return io_run(fn
, data
);
122 static VALUE
nogvl_splice(void *ptr
)
124 struct splice_args
*a
= ptr
;
126 return (VALUE
)splice(a
->fd_in
, a
->off_in
, a
->fd_out
, a
->off_out
,
130 static long do_splice(int argc
, VALUE
*argv
, unsigned dflags
)
133 VALUE fd_in
, off_in
, fd_out
, off_out
, len
, flags
;
134 struct splice_args a
;
136 rb_scan_args(argc
, argv
, "51",
137 &fd_in
, &off_in
, &fd_out
, &off_out
, &len
, &flags
);
139 a
.off_in
= NIL_P(off_in
) ? NULL
: (i
= NUM2OFFT(off_in
), &i
);
140 a
.off_out
= NIL_P(off_out
) ? NULL
: (o
= NUM2OFFT(off_out
), &o
);
141 a
.fd_in
= my_fileno(fd_in
);
142 a
.fd_out
= my_fileno(fd_out
);
143 a
.len
= (size_t)NUM2ULONG(len
);
144 a
.flags
= NIL_P(flags
) ? dflags
: NUM2UINT(flags
) | dflags
;
146 return (long)io_run(nogvl_splice
, &a
);
151 * IO.splice(fd_in, off_in, fd_out, off_out, len) => integer
152 * IO.splice(fd_in, off_in, fd_out, off_out, len, flags) => integer
154 * Splice +len+ bytes from/to a pipe. Either +fd_in+ or +fd_out+
155 * MUST be a pipe. +fd_in+ and +fd_out+ may BOTH be pipes as of
156 * Linux 2.6.31 or later.
158 * +off_in+ and +off_out+ if non-nil may be used to
159 * specify an offset for the non-pipe file descriptor.
161 * +flags+ defaults to zero if unspecified.
162 * +flags+ may be a bitmask of the following flags:
164 * IO::Splice::F_MOVE, IO::Splice::F_NONBLOCK, IO::Splice::F_MORE
166 * Returns the number of bytes spliced.
167 * Raises EOFError when +fd_in+ has reached end of file.
168 * Raises Errno::EAGAIN if the IO::Splice::F_NONBLOCK flag is set
169 * and the pipe has no data to read from or space to write to. May
170 * also raise Errno::EAGAIN if the non-pipe descriptor has no data
171 * to read from or space to write to.
173 * rd, wr = (pipe = IO.pipe).map { |io| io.fileno }
174 * src_io, dst_io = File.open("/path/to/src"), File.open("/path/to/dst")
175 * src, dst = src_io.fileno, dst_io.fileno
177 * nr = IO.splice(src, nil, wr, nil, IO::Splice::PIPE_CAPA, 0)
178 * IO.splice(rd, nil, dst, nil, nr, 0)
180 * As splice never exposes buffers to userspace, it will not take
181 * into account userspace buffering done by Ruby or stdio. It is
182 * also not subject to encoding/decoding filters under Ruby 1.9.
184 * Consider using IO.trysplice if you are using non-blocking I/O on
185 * both descriptors as it avoids the cost of raising common Errno::EAGAIN
188 * See manpage for full documentation:
189 * http://kernel.org/doc/man-pages/online/pages/man2/splice.2.html
191 static VALUE
my_splice(int argc
, VALUE
*argv
, VALUE self
)
193 long n
= do_splice(argc
, argv
, 0);
198 rb_sys_fail("splice");
204 * IO.trysplice(fd_in, off_in, fd_out, off_out, len) => integer
205 * IO.trysplice(fd_in, off_in, fd_out, off_out, len, flags) => integer
207 * Exactly like IO.splice, except +:EAGAIN+ is returned when either
208 * the read or write end would block instead of raising Errno::EAGAIN.
210 * IO::Splice::F_NONBLOCK is always passed for the pipe descriptor,
211 * but this can still block if the non-pipe descriptor is blocking.
213 * See IO.splice documentation for more details.
215 static VALUE
trysplice(int argc
, VALUE
*argv
, VALUE self
)
217 long n
= do_splice(argc
, argv
, SPLICE_F_NONBLOCK
);
224 rb_sys_fail("splice");
236 /* runs without GVL */
237 static VALUE
nogvl_tee(void *ptr
)
239 struct tee_args
*a
= ptr
;
241 return (VALUE
)tee(a
->fd_in
, a
->fd_out
, a
->len
, a
->flags
);
244 static long do_tee(int argc
, VALUE
*argv
, unsigned dflags
)
246 VALUE fd_in
, fd_out
, len
, flags
;
249 rb_scan_args(argc
, argv
, "31", &fd_in
, &fd_out
, &len
, &flags
);
250 a
.fd_in
= my_fileno(fd_in
);
251 a
.fd_out
= my_fileno(fd_out
);
252 a
.len
= (size_t)NUM2ULONG(len
);
253 a
.flags
= NIL_P(flags
) ? dflags
: NUM2UINT(flags
) | dflags
;
255 return (long)nb_io_run(nogvl_tee
, &a
, a
.flags
);
260 * IO.tee(fd_in, fd_out, len) => integer
261 * IO.tee(fd_in, fd_out, len, flags) => integer
263 * Copies up to +len+ bytes of data from +fd_in+ to +fd_out+. +fd_in+
264 * and +fd_out+ must both refer to pipe descriptors. +fd_in+ and +fd_out+
265 * may not be endpoints of the same pipe.
267 * +flags+ may be zero (the default) or IO::Splice::F_NONBLOCK
268 * Other IO::Splice flags are currently unimplemented or have no effect.
270 * Returns the number of bytes duplicated if successful.
271 * Raises EOFError when +fd_in+ is closed and emptied.
272 * Raises Errno::EAGAIN when +fd_in+ is empty and/or +fd_out+ is full
273 * and +flags+ contains IO::Splice::F_NONBLOCK
275 * Consider using IO.trytee if you are using IO::Splice::F_NONBLOCK
276 * as it avoids the cost of raising common Errno::EAGAIN exceptions.
278 * See manpage for full documentation:
279 * http://kernel.org/doc/man-pages/online/pages/man2/tee.2.html
281 static VALUE
my_tee(int argc
, VALUE
*argv
, VALUE self
)
283 long n
= do_tee(argc
, argv
, 0);
295 * IO.trytee(fd_in, fd_out, len) => integer
296 * IO.trytee(fd_in, fd_out, len, flags) => integer
298 * Exactly like IO.tee, except +:EAGAIN+ is returned when either
299 * the read or write end would block instead of raising Errno::EAGAIN.
301 * IO::Splice::F_NONBLOCK is always passed for the pipe descriptor,
302 * but this can still block if the non-pipe descriptor is blocking.
304 * See IO.tee documentation for more details.
306 static VALUE
trytee(int argc
, VALUE
*argv
, VALUE self
)
308 long n
= do_tee(argc
, argv
, SPLICE_F_NONBLOCK
);
321 struct vmsplice_args
{
324 unsigned long nr_segs
;
328 static VALUE
nogvl_vmsplice(void *ptr
)
330 struct vmsplice_args
*a
= ptr
;
332 return (VALUE
)vmsplice(a
->fd
, a
->iov
, a
->nr_segs
, a
->flags
);
335 /* this can't be a function since we use alloca() */
336 #define ARY2IOVEC(iov,iovcnt,expect,ary) \
341 cur = RARRAY_PTR(ary); \
342 n = RARRAY_LEN(ary); \
344 rb_raise(rb_eArgError, "array is larger than IOV_MAX"); \
345 iov = tmp = alloca(sizeof(struct iovec) * n); \
348 for (; --n >= 0; tmp++, cur++) { \
349 Check_Type(*cur, T_STRING); \
350 tmp->iov_base = RSTRING_PTR(*cur); \
351 tmp->iov_len = RSTRING_LEN(*cur); \
352 expect += tmp->iov_len; \
356 static void advance_vmsplice_args(struct vmsplice_args
*a
, long n
)
358 struct iovec
*new_iov
= a
->iov
;
361 /* skip over iovecs we've already written completely */
362 for (i
= 0; i
< a
->nr_segs
; i
++, new_iov
++) {
366 * partially written iov,
367 * modify and retry with current iovec in
370 if (new_iov
->iov_len
> (size_t)n
) {
371 VALUE base
= (VALUE
)new_iov
->iov_base
;
373 new_iov
->iov_len
-= n
;
374 new_iov
->iov_base
= (void *)(base
+ n
);
378 n
-= new_iov
->iov_len
;
381 /* setup to retry without the already-written iovecs */
388 * IO.vmsplice(fd, string_array) => integer
389 * IO.vmsplice(fd, string_array, flags) => integer
390 * IO.vmsplice(fd, string) => integer
391 * IO.vmsplice(fd, string, flags) => integer
393 * Transfers an array of strings into the pipe descriptor given by fd.
394 * +fd+ must be the writable end of a pipe.
396 * This may allow the kernel to avoid data copies in some cases.
397 * but is (probably) of limited usefulness in Ruby. If you have
398 * use cases or ideas for making this more useful for Ruby users,
399 * please tell us at ruby.io.splice@librelist.com!
401 * Also consider the "sendfile" RubyGem or IO.copy_stream in Ruby 1.9
402 * if you want to do zero-copy file transfers to pipes or sockets. As
403 * of Linux 2.6.33, sendfile(2) can copy to any output descriptor,
406 * See manpage for full documentation:
407 * http://kernel.org/doc/man-pages/online/pages/man2/vmsplice.2.html
409 static VALUE
my_vmsplice(int argc
, VALUE
* argv
, VALUE self
)
413 struct vmsplice_args a
;
414 VALUE fd
, data
, flags
;
416 rb_scan_args(argc
, argv
, "21", &fd
, &data
, &flags
);
418 switch (TYPE(data
)) {
422 iov
.iov_base
= RSTRING_PTR(data
);
423 iov
.iov_len
= (size_t)(left
= (ssize_t
)RSTRING_LEN(data
));
429 ARY2IOVEC(a
.iov
, a
.nr_segs
, left
, data
);
432 rb_raise(rb_eTypeError
, "wrong argument type %s "
433 "(expected a String or Array of strings)",
434 rb_obj_classname(data
));
436 a
.fd
= my_fileno(fd
);
437 a
.flags
= NIL_P(flags
) ? 0 : NUM2UINT(flags
);
440 long n
= (long)nb_io_run(nogvl_vmsplice
, &a
, a
.flags
);
443 if (errno
== EAGAIN
) {
444 if (a
.flags
& SPLICE_F_NONBLOCK
)
445 rb_sys_fail("vmsplice");
446 else if (rb_io_wait_writable(a
.fd
))
448 /* fall through on error */
451 * unlikely to hit this case, return the
452 * already written bytes, we'll let the next
453 * write (or close) fail instead
457 rb_sys_fail("vmsplice");
464 advance_vmsplice_args(&a
, n
);
472 * reader, writer = IO.pipe
473 * reader.pipe_size => integer
475 * Returns the pipe capacity of the underlying pipe in bytes. The
476 * default capacity is 65536 bytes since Linux 2.6.11, and 4096 bytes
477 * in previous kernels.
479 * Since the pipe is a circular buffer in the same kernel, the size
480 * of the reader is exactly the same as the size of the writer.
482 * This method is only exposed on Linux 2.6.35 or later.
484 static VALUE
pipe_size(VALUE self
)
486 int size
= fcntl(my_fileno(self
), F_GETPIPE_SZ
);
489 rb_sys_fail("fcntl(F_GETPIPE_SZ)");
491 return INT2NUM(size
);
496 * reader, writer = IO.pipe
497 * reader.pipe_size = integer
499 * Sets and returns the pipe capacity of the underlying pipe in bytes.
501 * This MUST be a power-of-two, or Errno::EINVAL will be raised.
502 * Linux will silently increase this to be equal to the page size
503 * (4096 bytes on most architectures) if the specified value is
504 * less than the size of a page.
506 * For users without CAP_SYS_RESOURCE, this raises Errno::EPERM when
507 * attempting to specify a value greater than the value in
508 * /proc/sys/fs/pipe-max-size.
510 * Since the pipe is a circular buffer in the same kernel, the size
511 * of the reader is exactly the same as the size of the writer.
513 * Raises Errno::EBUSY if the assigned value is less than
514 * the currently filled portion of the pipe.
516 * This method is only exposed on Linux 2.6.35 or later.
518 static VALUE
set_pipe_size(VALUE self
, VALUE size
)
520 int fd
= my_fileno(self
);
521 int bytes
= NUM2INT(size
);
522 int rv
= fcntl(fd
, F_SETPIPE_SZ
, bytes
);
525 if (errno
== ENOMEM
) {
527 rv
= fcntl(fd
, F_SETPIPE_SZ
, bytes
);
530 rb_sys_fail("fcntl(F_SETPIPE_SZ)");
536 void Init_io_splice_ext(void)
538 VALUE mSplice
= rb_define_module_under(rb_cIO
, "Splice");
539 struct utsname utsname
;
541 rb_define_singleton_method(rb_cIO
, "splice", my_splice
, -1);
542 rb_define_singleton_method(rb_cIO
, "trysplice", trysplice
, -1);
543 rb_define_singleton_method(rb_cIO
, "tee", my_tee
, -1);
544 rb_define_singleton_method(rb_cIO
, "trytee", trytee
, -1);
545 rb_define_singleton_method(rb_cIO
, "vmsplice", my_vmsplice
, -1);
548 * Attempt to move pages instead of copying. This is only a hint
549 * and support for it was removed in Linux 2.6.21. It will be
550 * re-added for FUSE filesystems only in Linux 2.6.35.
552 rb_define_const(mSplice
, "F_MOVE", UINT2NUM(SPLICE_F_MOVE
));
555 * Do not block on pipe I/O. This flag only affects the pipe(s)
556 * being spliced from/to and has no effect on the non-pipe
557 * descriptor (which requires non-blocking operation to be set
560 * The non-blocking flag (O_NONBLOCK) on the pipe descriptors
561 * themselves are ignored by this family of functions, and
562 * using this flag is the only way to get non-blocking operation
565 rb_define_const(mSplice
, "F_NONBLOCK", UINT2NUM(SPLICE_F_NONBLOCK
));
568 * Indicate that there may be more data coming into the outbound
569 * descriptor. This can allow the kernel to avoid sending partial
570 * frames from sockets. Currently only used with splice.
572 rb_define_const(mSplice
, "F_MORE", UINT2NUM(SPLICE_F_MORE
));
575 * Only usable by vmsplice. This flag probably not useful in the
576 * context of Ruby applications which cannot control alignment.
578 rb_define_const(mSplice
, "F_GIFT", UINT2NUM(SPLICE_F_GIFT
));
581 * The maximum size of an atomic write to a pipe
582 * POSIX requires this to be at least 512 bytes.
583 * Under Linux, this is 4096 bytes.
585 rb_define_const(mSplice
, "PIPE_BUF", UINT2NUM(PIPE_BUF
));
587 if (uname(&utsname
) == -1)
588 rb_sys_fail("uname");
590 /* includes 2.6.35-rc[1-6] */
591 if (strcmp(utsname
.release
, "2.6.35") >= 0) {
592 rb_define_method(rb_cIO
, "pipe_size", pipe_size
, 0);
593 rb_define_method(rb_cIO
, "pipe_size=", set_pipe_size
, 1);
596 * fcntl() command constant used to return the size of a pipe.
597 * This constant is only defined when running Linux 2.6.35
598 * or later. For convenience, use IO#pipe_size instead.
600 rb_define_const(mSplice
, "F_GETPIPE_SZ",
601 UINT2NUM(F_GETPIPE_SZ
));
604 * fcntl() command constant used to set the size of a pipe.
605 * This constant is only defined when running Linux 2.6.35
606 * or later. For convenience, use IO#pipe_size= instead.
608 rb_define_const(mSplice
, "F_SETPIPE_SZ",
609 UINT2NUM(F_SETPIPE_SZ
));
612 sym_EAGAIN
= ID2SYM(rb_intern("EAGAIN"));