1 # -*- encoding: binary -*-
2 require 'io_splice_ext'
8 # the version of IO::Splice, currently 2.1.0
11 # The maximum default capacity of the pipe in bytes.
12 # Under stock Linux, this is 65536 bytes as of 2.6.11, and 4096 before
13 # We detect this at runtime as it is easy to recompile the kernel
14 # and set a new value.
15 # Starting with Linux 2.6.35, pipe capacity will be tunable
16 # and this will only represent the default capacity of a
23 n += wr.write_nonblock(buf)
32 # copies the contents of the IO object given by +src+ to +dst+
33 # If len is specified, then only len bytes are copied. Otherwise
34 # the copy will be until EOF is reached on the +src+.
35 # +src+ and +dst+ must be IO objects or respond to +to_io+
36 def Splice.copy_stream(src, dst, len = nil, src_offset = nil)
38 src.kind_of?(String) and close << (src = File.open(src, 'rb'))
39 dst.kind_of?(String) and close << (dst = File.open(dst, 'wb'))
40 src, dst = src.to_io, dst.to_io
42 src.sysseek(src_offset) if src_offset
43 select_args = selectable(src, dst)
45 if src.stat.pipe? || dst.stat.pipe?
47 len -= full(src, dst, len, select_args) until len == 0
51 rv += partial(src, dst, PIPE_CAPA, select_args)
61 nr = partial(src, w, len, select_args)
62 len -= full(r, dst, nr, select_args)
67 nr = partial(src, w, PIPE_CAPA, select_args)
68 rv += full(r, dst, nr, select_args)
77 close.each { |io| io.close }
80 # splice the full amount specified from +src+ to +dst+
81 # Either +dst+ or +src+ must be a pipe. +dst+ and +src+
82 # may BOTH be pipes in Linux 2.6.31 or later.
83 # This will block and wait for IO completion of +len+
84 # bytes. Returns the nubmer of bytes actually spliced (always +len+)
85 # The +_select_args+ parameter is reserved for internal use and
86 # may be removed in future versions. Do not write code that
87 # depends on +_select_args+.
88 def Splice.full(src, dst, len, _select_args = selectable(src, dst))
90 nr -= partial(src, dst, nr, _select_args) until nr == 0
94 # splice up to +len+ bytes from +src+ to +dst+.
95 # Either +dst+ or +src+ must be a pipe. +dst+ and +src+
96 # may BOTH be pipes in Linux 2.6.31 or later.
97 # Returns the number of bytes actually spliced.
98 # Like IO#readpartial, this never returns Errno::EAGAIN
99 # The +_select_args+ parameter is reserved for internal use and
100 # may be removed in future versions. Do not write code that
101 # depends on +_select_args+.
102 def Splice.partial(src, dst, len, _select_args = selectable(src, dst))
104 IO.splice(src, nil, dst, nil, len, F_MOVE)
106 IO.select(*_select_args)
111 # returns an array suitable for splat-ing to IO.select for blocking I/O
112 def Splice.selectable(src, dst)
114 src.stat.pipe? or rv[0] = [ src ]
115 dst.stat.pipe? or rv[1] = [ dst ]