Class: Win32::Pipe
- Inherits:
-
Object
- Object
- Win32::Pipe
- Includes:
- Windows::Constants, Windows::Functions, Windows::Structs
- Defined in:
- lib/win32/pipe.rb
Overview
The Pipe class is an abstract base class for the Pipe::Server and Pipe::Client classes. Do not use this directly.
Defined Under Namespace
Classes: Client, Error, Server
Constant Summary collapse
- VERSION =
The version of this library
'0.4.0'
- DEFAULT_PIPE_BUFFER_SIZE =
:nodoc:
4096
- PIPE_TIMEOUT =
:nodoc:
5000
- WAIT =
Blocking mode is enabled
PIPE_WAIT
- NOWAIT =
Nonblocking mode is enabled
PIPE_NOWAIT
- ACCESS_DUPLEX =
The pipe is bi-directional. Both server and client processes can read from and write to the pipe.
PIPE_ACCESS_DUPLEX
- ACCESS_INBOUND =
The flow of data in the pipe goes from client to server only.
PIPE_ACCESS_INBOUND
- ACCESS_OUTBOUND =
The flow of data in the pipe goes from server to client only.
PIPE_ACCESS_OUTBOUND
- TYPE_BYTE =
Data is written to the pipe as a stream of bytes.
PIPE_TYPE_BYTE
- TYPE_MESSAGE =
Data is written to the pipe as a stream of messages.
PIPE_TYPE_MESSAGE
- READMODE_BYTE =
Data is read from the pipe as a stream of bytes.
PIPE_READMODE_BYTE
- READMODE_MESSAGE =
Data is read from the pipe as a stream of messages.
PIPE_READMODE_MESSAGE
- FIRST_PIPE_INSTANCE =
All instances beyond the first will fail with access denied errors.
FILE_FLAG_FIRST_PIPE_INSTANCE
- WRITE_THROUGH =
Functions do not return until the data is written across the network.
FILE_FLAG_WRITE_THROUGH
- OVERLAPPED =
Overlapped mode enables asynchronous communication.
FILE_FLAG_OVERLAPPED
- DEFAULT_PIPE_MODE =
The default pipe mode
PIPE_WAIT
- DEFAULT_OPEN_MODE =
The default open mode
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH
Constants included from Windows::Constants
Windows::Constants::ERROR_IO_PENDING, Windows::Constants::ERROR_PIPE_BUSY, Windows::Constants::ERROR_PIPE_CONNECTED, Windows::Constants::ERROR_PIPE_LISTENING, Windows::Constants::ERROR_SUCCESS, Windows::Constants::FILE_ATTRIBUTE_NORMAL, Windows::Constants::FILE_FLAG_FIRST_PIPE_INSTANCE, Windows::Constants::FILE_FLAG_OVERLAPPED, Windows::Constants::FILE_FLAG_WRITE_THROUGH, Windows::Constants::FILE_SHARE_READ, Windows::Constants::FILE_SHARE_WRITE, Windows::Constants::GENERIC_READ, Windows::Constants::GENERIC_WRITE, Windows::Constants::INFINITE, Windows::Constants::INVALID_HANDLE_VALUE, Windows::Constants::NMPWAIT_WAIT_FOREVER, Windows::Constants::OPEN_EXISTING, Windows::Constants::PIPE_ACCESS_DUPLEX, Windows::Constants::PIPE_ACCESS_INBOUND, Windows::Constants::PIPE_ACCESS_OUTBOUND, Windows::Constants::PIPE_CLIENT_END, Windows::Constants::PIPE_NOWAIT, Windows::Constants::PIPE_READMODE_BYTE, Windows::Constants::PIPE_READMODE_MESSAGE, Windows::Constants::PIPE_SERVER_END, Windows::Constants::PIPE_TYPE_BYTE, Windows::Constants::PIPE_TYPE_MESSAGE, Windows::Constants::PIPE_UNLIMITED_INSTANCES, Windows::Constants::PIPE_WAIT, Windows::Constants::WAIT_OBJECT_0, Windows::Constants::WAIT_TIMEOUT
Instance Attribute Summary collapse
-
#buffer ⇒ Object
readonly
The data still in the pipe’s buffer.
-
#name ⇒ Object
readonly
The full name of the pipe, e.g.
-
#open_mode ⇒ Object
readonly
The pipe mode of the pipe.
-
#pipe_mode ⇒ Object
readonly
The open mode of the pipe.
-
#size ⇒ Object
(also: #length)
readonly
The number of bytes to be written to the pipe.
-
#transferred ⇒ Object
readonly
The number of characters that are actually transferred over the pipe.
Instance Method Summary collapse
-
#asynchronous? ⇒ Boolean
Returns whether or not the pipe is asynchronous.
-
#close ⇒ Object
Closes the pipe.
-
#disconnect ⇒ Object
Disconnects the pipe.
-
#initialize(name, pipe_mode = DEFAULT_PIPE_MODE, open_mode = DEFAULT_OPEN_MODE, pipe_buffer_size = DEFAULT_PIPE_BUFFER_SIZE) ⇒ Pipe
constructor
Abstract initializer for base class.
-
#pending? ⇒ Boolean
Returns whether or not there is a pending IO operation on the pipe.
-
#read(read_size = @ffi_buffer.size) ⇒ Object
Reads data from the pipe.
-
#wait(max_time = nil) ⇒ Object
Returns the pipe object if an event (such as a client connection) occurs within the
max_time
specified (in seconds). -
#write(data) ⇒ Object
Writes ‘data’ to the pipe.
Constructor Details
#initialize(name, pipe_mode = DEFAULT_PIPE_MODE, open_mode = DEFAULT_OPEN_MODE, pipe_buffer_size = DEFAULT_PIPE_BUFFER_SIZE) ⇒ Pipe
Abstract initializer for base class. This handles automatic prepending of ‘\.pipe' to each named pipe so that you don’t have to. Don’t use this directly. Add the full implementation in subclasses.
The default pipe mode is PIPE_WAIT.
The default open mode is FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/win32/pipe.rb', line 93 def initialize(name, pipe_mode = DEFAULT_PIPE_MODE, open_mode = DEFAULT_OPEN_MODE, pipe_buffer_size = DEFAULT_PIPE_BUFFER_SIZE) @name = "\\\\.\\pipe\\" + name @pipe_mode = pipe_mode.nil? ? DEFAULT_PIPE_MODE : pipe_mode @open_mode = open_mode.nil? ? DEFAULT_OPEN_MODE : open_mode @pipe = nil @pending_io = false @buffer = '' @ffi_buffer = FFI::Buffer.new( pipe_buffer_size ) @size = 0 @overlapped = nil @transferred = 0 @asynchronous = false @pipe_buffer_size = pipe_buffer_size if open_mode & FILE_FLAG_OVERLAPPED > 0 @asynchronous = true end if @asynchronous @event = CreateEvent(nil, 1, 1, nil) @overlapped = Overlapped.new @overlapped[:hEvent] = @event end end |
Instance Attribute Details
#buffer ⇒ Object (readonly)
The data still in the pipe’s buffer
68 69 70 |
# File 'lib/win32/pipe.rb', line 68 def buffer @buffer end |
#name ⇒ Object (readonly)
The full name of the pipe, e.g. “\\.\pipe\my_pipe”
77 78 79 |
# File 'lib/win32/pipe.rb', line 77 def name @name end |
#open_mode ⇒ Object (readonly)
The pipe mode of the pipe.
80 81 82 |
# File 'lib/win32/pipe.rb', line 80 def open_mode @open_mode end |
#pipe_mode ⇒ Object (readonly)
The open mode of the pipe.
83 84 85 |
# File 'lib/win32/pipe.rb', line 83 def pipe_mode @pipe_mode end |
#size ⇒ Object (readonly) Also known as: length
The number of bytes to be written to the pipe.
71 72 73 |
# File 'lib/win32/pipe.rb', line 71 def size @size end |
#transferred ⇒ Object (readonly)
The number of characters that are actually transferred over the pipe.
74 75 76 |
# File 'lib/win32/pipe.rb', line 74 def transferred @transferred end |
Instance Method Details
#asynchronous? ⇒ Boolean
Returns whether or not the pipe is asynchronous.
139 140 141 |
# File 'lib/win32/pipe.rb', line 139 def asynchronous? @asynchronous end |
#close ⇒ Object
Closes the pipe.
127 128 129 |
# File 'lib/win32/pipe.rb', line 127 def close CloseHandle(@pipe) if @pipe end |
#disconnect ⇒ Object
Disconnects the pipe.
121 122 123 |
# File 'lib/win32/pipe.rb', line 121 def disconnect DisconnectNamedPipe(@pipe) if @pipe end |
#pending? ⇒ Boolean
Returns whether or not there is a pending IO operation on the pipe.
133 134 135 |
# File 'lib/win32/pipe.rb', line 133 def pending? @pending_io end |
#read(read_size = @ffi_buffer.size) ⇒ Object
Reads data from the pipe. You can read data from either end of a named pipe.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/win32/pipe.rb', line 146 def read(read_size = @ffi_buffer.size) bytes = FFI::MemoryPointer.new(:ulong) raise Error, "no pipe created" unless @pipe if @asynchronous bool = ReadFile(@pipe, @ffi_buffer, read_size, bytes, @overlapped) bytes_read = bytes.read_ulong if bool && bytes_read > 0 @pending_io = false @buffer = @ffi_buffer.get_string(0, bytes_read) return true end error = GetLastError() if !bool && error == ERROR_IO_PENDING @pending_io = true return true end return false else unless ReadFile(@pipe, @ffi_buffer, read_size, bytes, nil) raise SystemCallError.new("ReadFile", FFI.errno) end @buffer = @ffi_buffer.get_string(0, bytes.read_ulong) end end |
#wait(max_time = nil) ⇒ Object
Returns the pipe object if an event (such as a client connection) occurs within the max_time
specified (in seconds). Otherwise, it returns false.
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/win32/pipe.rb', line 213 def wait(max_time = nil) unless @asynchronous raise Error, 'cannot wait in synchronous (blocking) mode' end max_time = max_time ? max_time * 1000 : INFINITE wait = WaitForSingleObject(@event, max_time) if wait == WAIT_TIMEOUT return false else if wait != WAIT_OBJECT_0 raise SystemCallError.new("WaitForSingleObject", FFI.errno) end end if @pending_io transferred = FFI::MemoryPointer.new(:ulong) bool = GetOverlappedResult(@pipe, @overlapped, transferred, 0) unless bool raise SystemCallError.new("GetOverlappedResult", FFI.errno) end @transferred = transferred.read_ulong @buffer = @ffi_buffer.get_string(0, @transferred) end self end |
#write(data) ⇒ Object
Writes ‘data’ to the pipe. You can write data to either end of a named pipe.
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 |
# File 'lib/win32/pipe.rb', line 179 def write(data) bytes = FFI::MemoryPointer.new(:ulong) raise Error, "no pipe created" unless @pipe if @asynchronous bool = WriteFile(@pipe, data, data.size, bytes, @overlapped) bytes_written = bytes.read_ulong if bool && bytes_written > 0 @pending_io = false return true end error = GetLastError() if !bool && error == ERROR_IO_PENDING @pending_io = true return true end return false else unless WriteFile(@pipe, data, data.size, bytes, nil) raise SystemCallError.new("WriteFile", FFI.errno) end return true end end |