Module: IO::Splice
- Defined in:
- lib/io/splice/mri_18.rb,
lib/io/splice.rb
Constant Summary collapse
- PIPE_CAPA =
The maximum default capacity of the pipe in bytes. Under stock Linux, this is 65536 bytes as of 2.6.11, and 4096 before We detect this at runtime as it is easy to recompile the kernel and set a new value. Starting with Linux 2.6.35, pipe capacity will be tunable and this will only represent the default capacity of a newly-created pipe.
begin rd, wr = IO.pipe buf = ' ' * PIPE_BUF n = 0 begin n += wr.write_nonblock(buf) rescue Errno::EAGAIN break end while true wr.close rd.close n end
Class Method Summary collapse
-
.__deprecated ⇒ Object
:nodoc:.
-
.copy_stream(src, dst, len = nil, src_offset = nil) ⇒ Object
copies the contents of the IO object given by
srctodstIflenis specified, then onlylenbytes are copied andEOFErroris raised if fewer thanlenbytes could be copied. -
.full(src, dst, len, src_offset) ⇒ Object
splice the full amount specified from
srctodstEitherdstorsrcmust be a pipe. -
.need_open?(obj) ⇒ Boolean
:nodoc:.
-
.partial(src, dst, len, src_offset) ⇒ Object
splice up to
lenbytes fromsrctodst.
Class Method Details
.__deprecated ⇒ Object
:nodoc:
8 9 10 11 12 13 |
# File 'lib/io/splice.rb', line 8 def self.__deprecated # :nodoc: return if @warned warn("IO::Splice.{copy_stream,full} are deprecated " \ "and to be removed in io_splice 5.x") @warned = true end |
.copy_stream(src, dst, len = nil, src_offset = nil) ⇒ Object
copies the contents of the IO object given by src to dst If len is specified, then only len bytes are copied and EOFError is raised if fewer than len bytes could be copied. Otherwise the copy will be until EOF is reached on the src. src and dst must be IO objects or respond to to_io
Unlike IO.copy_stream, this does not take into account userspace I/O buffers nor IO-like objects with no underlying file descriptor (e.g. StringIO).
This is unsafe for socket-to-socket copies unless there is an active (blocking) reader on the other end.
This method is deprecated and will be removed in a future, as it is potentially unsafe for socket-to-socket operations and difficult-to-use. IO.copy_stream on Linux 2.6.33 and later allows using sendfile for file-to-file copies, so this offers no advantage.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/io/splice.rb', line 58 def self.copy_stream(src, dst, len = nil, src_offset = nil) __deprecated close = [] need_open?(src) and close << (src = File.open(src)) need_open?(dst) and close << (dst = File.open(dst, "w")) rv = len src, dst = src.to_io, dst.to_io if src.stat.pipe? || dst.stat.pipe? return full(src, dst, len, src_offset) if len rv = 0 while n = partial(src, dst, MAX_AT_ONCE, src_offset) rv += n src_offset += n if src_offset end else r, w = tmp = IO.pipe close.concat(tmp) rv = 0 if len while len != 0 && n = partial(src, w, len, src_offset) src_offset += n if src_offset rv += n len -= full(r, dst, n, nil) end else while n = partial(src, w, MAX_AT_ONCE, src_offset) src_offset += n if src_offset rv += full(r, dst, n, nil) end end end rv ensure close.each { |io| io.close } end |
.full(src, dst, len, src_offset) ⇒ Object
splice the full amount specified from src to dst Either dst or src must be a pipe. dst and src may BOTH be pipes in Linux 2.6.31 or later. This will block and wait for IO completion of len Raises EOFError if end of file is reached. bytes. Returns the number of bytes actually spliced (always len) unless src does not have len bytes to read.
Do not use this method to splice a socket src into a pipe dst unless there is another process or native thread doing a blocking read on the other end of the dst pipe.
This method is safe for splicing a pipe src into any type of dst IO.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/io/splice.rb', line 109 def self.full(src, dst, len, src_offset) dst.to_io.nonblock = src.to_io.nonblock = true spliced = 0 case n = IO.trysplice(src, src_offset, dst, nil, len, IO::Splice::F_MOVE) when :EAGAIN src.to_io.wait IO.select(nil, [dst]) when Integer spliced += n len -= n src_offset += n if src_offset when nil break end while len > 0 spliced end |
.need_open?(obj) ⇒ Boolean
:nodoc:
36 37 38 39 |
# File 'lib/io/splice.rb', line 36 def self.need_open?(obj) # :nodoc: return false if obj.respond_to?(:to_io) obj.respond_to?(:to_path) || obj.kind_of?(String) end |
.partial(src, dst, len, src_offset) ⇒ Object
splice up to len bytes from src to dst. Either dst or src must be a pipe. dst and src may BOTH be pipes in Linux 2.6.31 or later. Returns the number of bytes actually spliced. Like IO#readpartial, this never returns Errno::EAGAIN
119 120 121 122 123 124 125 126 127 |
# File 'lib/io/splice.rb', line 119 def self.partial(src, dst, len, src_offset) dst.to_io.nonblock = src.to_io.nonblock = true begin src.to_io.wait IO.select(nil, [dst]) rv = IO.trysplice(src, src_offset, dst, nil, len, IO::Splice::F_MOVE) end while rv == :EAGAIN rv end |