Module: Rex::Proto::Ssh::IOMergeAbstraction
- Included in:
- ChannelFD
- Defined in:
- lib/rex/proto/ssh/connection.rb
Overview
A modified Rex::IO::Stream for separate file descriptors consumers are responsible for relevant initialization and fd_rd+fd_wr methods to expose selectable R/W IOs.
Instance Method Summary collapse
- #close ⇒ Object
- #closed? ⇒ Boolean
-
#has_read_data?(timeout = nil) ⇒ Boolean
Polls the stream to see if there is any read data available.
- #inspect ⇒ Object
-
#read(length = nil, opts = {}) ⇒ Object
This method reads data of the supplied length from the stream.
- #write(buf, opts = {}) ⇒ Object
Instance Method Details
#close ⇒ Object
254 255 256 257 |
# File 'lib/rex/proto/ssh/connection.rb', line 254 def close fd_rd.close if (fd_rd and !fd_rd.closed?) fd_wr.close if (fd_wr and !fd_wr.closed?) end |
#closed? ⇒ Boolean
259 260 261 |
# File 'lib/rex/proto/ssh/connection.rb', line 259 def closed? (fd_rd.nil? or fd_rd.closed?) and (fd_wr.nil? or fd_wr.closed?) end |
#has_read_data?(timeout = nil) ⇒ Boolean
Polls the stream to see if there is any read data available. Returns true if data is available for reading, otherwise false is returned.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/rex/proto/ssh/connection.rb', line 231 def has_read_data?(timeout = nil) # Allow a timeout of "0" that waits almost indefinitely for input, this # mimics the behavior of Rex::ThreadSafe.select() and fixes some corner # cases of unintentional no-wait timeouts. timeout = 3600 if (timeout and timeout == 0) begin if ((rv = ::IO.select([ fd_rd ], nil, nil, timeout)) and (rv[0]) and (rv[0][0] == fd_rd)) true else false end rescue ::Errno::EBADF, ::Errno::ENOTSOCK raise ::EOFError rescue StreamClosedError, ::IOError, ::EOFError, ::Errno::EPIPE # Return false if the socket is dead return false end end |
#inspect ⇒ Object
175 176 177 |
# File 'lib/rex/proto/ssh/connection.rb', line 175 def inspect "#{self.class}(#{fd_rd.inspect}|#{fd_wr.inspect})" end |
#read(length = nil, opts = {}) ⇒ Object
This method reads data of the supplied length from the stream.
213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/rex/proto/ssh/connection.rb', line 213 def read(length = nil, opts = {}) begin return fd_rd.read_nonblock( length ) rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK # Sleep for a half a second, or until we can read again Rex::ThreadSafe.select( [ fd_rd ], nil, nil, 0.5 ) # Decrement the block size to handle full sendQs better retry rescue ::IOError, ::Errno::EPIPE return nil end end |
#write(buf, opts = {}) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/rex/proto/ssh/connection.rb', line 179 def write(buf, opts = {}) total_sent = 0 total_length = buf.length block_size = 32768 begin while( total_sent < total_length ) s = Rex::ThreadSafe.select( nil, [ fd_wr ], nil, 0.2 ) if( s == nil || s[0] == nil ) next end data = buf[total_sent, block_size] sent = fd_wr.write_nonblock( data ) if sent > 0 total_sent += sent end end rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK # Sleep for a half a second, or until we can write again Rex::ThreadSafe.select( nil, [ fd_wr ], nil, 0.5 ) # Decrement the block size to handle full sendQs better block_size = 1024 # Try to write the data again retry rescue ::IOError, ::Errno::EPIPE return nil end total_sent end |