A thread-safe channel that multiplexes many threads onto a single 9P2000 connection.
The send/recv implementation is based on the XCB cookie approach: www.x.org/releases/X11R7.5/doc/libxcb/tutorial/#requestsreplies
- A
- C
- E
- N
- O
- R
-
- read,
- recv,
- remove,
- remove_fid
- S
- T
- W
- MODULE Rumai::IXP::Agent::MODES
- CLASS Rumai::IXP::Agent::FidStream
- CLASS Rumai::IXP::Agent::RangedPool
MODES | = | { 'r' => Topen::OREAD, 'w' => Topen::OWRITE, 't' => Topen::ORCLOSE, '+' => Topen::ORDWR, } |
[R] | msize |
- stream
- I/O stream on which a 9P2000 server is listening.
# File lib/rumai/ixp/transport.rb, line 26 def initialize stream @stream = stream @recv_buf = {} # tag => message @recv_lock = Mutex.new @tag_pool = RangedPool.new(0...BYTE2_MASK) @fid_pool = RangedPool.new(0...BYTE4_MASK) # establish connection with 9P2000 server req = Tversion.new( :tag => Fcall::NOTAG, :msize => Tversion::MSIZE, :version => Tversion::VERSION ) rsp = talk(req) unless req.version == rsp.version raise Error, "protocol mismatch: self=#{req.version.inspect} server=#{rsp.version.inspect}" end @msize = rsp.msize # authenticate the connection (not necessary for wmii) @auth_fid = Fcall::NOFID # attach to filesystem root @root_fid = @fid_pool.obtain attach @root_fid, @auth_fid end
Associates the given FID with the FS root.
Retires the given FID from use.
Creates a new file at the given path that is accessible using the given modes for a user having the given permission bits.
# File lib/rumai/ixp/transport.rb, line 382 def create path, mode = 'rw', perm = 0644 prefix = File.dirname(path) target = File.basename(path) mode = MODES.parse(mode) with_fid do |prefix_fid| walk_fid prefix_fid, prefix # create the file talk Tcreate.new( :fid => prefix_fid, :name => target, :perm => perm, :mode => mode ) end end
Returns the basenames of all files inside the directory at the given path.
See Dir::entries in the Ruby documentation.
Opens the given path for I/O access through a FidStream object. If a block is given, it is invoked with a FidStream object and the stream is closed afterwards.
See File::open in the Ruby documentation.
# File lib/rumai/ixp/transport.rb, line 199 def open path, mode = 'r' # :yields: FidStream mode = MODES.parse(mode) # open the file path_fid = walk(path) talk Topen.new( :fid => path_fid, :mode => mode ) stream = FidStream.new(self, path_fid, @msize) # return the file stream if block_given? begin yield stream ensure stream.close end else stream end end
Returns the content of the file/directory at the given path.
Returns the reply for the given ticket, which was previously given to you when you sent the corresponding request (Rumai::IXP::Fcall).
# File lib/rumai/ixp/transport.rb, line 124 def recv tag loop do reply = @recv_lock.synchronize do if @recv_buf.key? tag @recv_buf.delete tag else # reply was not in the receive buffer, so wait # for the next reply... hoping that it is ours msg = Fcall.from_9p(@stream) if msg.tag == tag msg else # we got someone else's reply, so buffer # it (for them to receive) and try again @recv_buf[msg.tag] = msg nil end end end if reply @tag_pool.release tag if reply.is_a? Rerror raise Error, reply.ename end return reply else # give other threads a chance to receive Thread.pass end end end
Deletes the file at the given path.
Deletes the file corresponding to the given FID and clunks the given FID.
Sends the given request (Rumai::IXP::Fcall) and returns a ticket that you can use later to receive the reply.
Returns information about the file at the given path.
Returns information about the file referenced by the given FID.
Sends the given request (Rumai::IXP::Fcall) and returns its reply.
Returns an FID corresponding to the given path.
Associates the given FID to the given path.