rumai 2.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CREDITS +2 -0
- data/bin/rumai +20 -8
- data/doc/api/classes/IO.html +72 -0
- data/doc/api/classes/Integer.html +110 -0
- data/doc/api/classes/Object.html +60 -0
- data/doc/api/classes/Rumai.html +867 -0
- data/doc/api/classes/Rumai/Area.html +836 -0
- data/doc/api/classes/Rumai/Chain.html +197 -0
- data/doc/api/classes/Rumai/Client.html +865 -0
- data/doc/api/classes/Rumai/ClientContainer.html +191 -0
- data/doc/api/classes/Rumai/ExportInstanceMethods.html +69 -0
- data/doc/api/classes/Rumai/IXP.html +131 -0
- data/doc/api/classes/Rumai/IXP/Agent.html +836 -0
- data/doc/api/classes/Rumai/IXP/Agent/FidStream.html +456 -0
- data/doc/api/classes/Rumai/IXP/Agent/MODES.html +108 -0
- data/doc/api/classes/Rumai/IXP/Agent/RangedPool.html +241 -0
- data/doc/api/classes/Rumai/IXP/Error.html +67 -0
- data/doc/api/classes/Rumai/IXP/Fcall.html +323 -0
- data/doc/api/classes/Rumai/IXP/Qid.html +153 -0
- data/doc/api/classes/Rumai/IXP/Rattach.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rauth.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rclunk.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rcreate.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rerror.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rflush.html +67 -0
- data/doc/api/classes/Rumai/IXP/Ropen.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rread.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rremove.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rstat.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rversion.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rwalk.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rwrite.html +67 -0
- data/doc/api/classes/Rumai/IXP/Rwstat.html +67 -0
- data/doc/api/classes/Rumai/IXP/Stat.html +252 -0
- data/doc/api/classes/Rumai/IXP/Stream.html +131 -0
- data/doc/api/classes/Rumai/IXP/Struct.html +315 -0
- data/doc/api/classes/Rumai/IXP/Struct/Field.html +415 -0
- data/doc/api/classes/Rumai/IXP/Struct/Field/CounteeField.html +153 -0
- data/doc/api/classes/Rumai/IXP/Struct/Field/CounterField.html +104 -0
- data/doc/api/classes/Rumai/IXP/Tattach.html +68 -0
- data/doc/api/classes/Rumai/IXP/Tauth.html +67 -0
- data/doc/api/classes/Rumai/IXP/Tclunk.html +67 -0
- data/doc/api/classes/Rumai/IXP/Tcreate.html +68 -0
- data/doc/api/classes/Rumai/IXP/Terror.html +110 -0
- data/doc/api/classes/Rumai/IXP/Tflush.html +67 -0
- data/doc/api/classes/Rumai/IXP/Topen.html +165 -0
- data/doc/api/classes/Rumai/IXP/Tread.html +67 -0
- data/doc/api/classes/Rumai/IXP/Tremove.html +67 -0
- data/doc/api/classes/Rumai/IXP/Tstat.html +67 -0
- data/doc/api/classes/Rumai/IXP/Tversion.html +86 -0
- data/doc/api/classes/Rumai/IXP/Twalk.html +68 -0
- data/doc/api/classes/Rumai/IXP/Twrite.html +68 -0
- data/doc/api/classes/Rumai/IXP/Twstat.html +67 -0
- data/doc/api/classes/Rumai/Node.html +817 -0
- data/doc/api/classes/Rumai/View.html +818 -0
- data/doc/api/classes/Rumai/WidgetImpl.html +65 -0
- data/doc/api/classes/Rumai/WidgetNode.html +68 -0
- data/doc/api/classes/String.html +163 -0
- data/doc/api/classes/StringIO.html +72 -0
- data/doc/api/classes/Time.html +156 -0
- data/doc/api/created.rid +1 -0
- data/doc/api/css/main.css +263 -0
- data/doc/api/css/panel.css +383 -0
- data/doc/api/css/reset.css +53 -0
- data/doc/api/files/CREDITS.html +64 -0
- data/doc/api/files/LICENSE.html +76 -0
- data/doc/api/files/lib/rumai/fs_rb.html +75 -0
- data/doc/api/files/lib/rumai/ixp/message_rb.html +91 -0
- data/doc/api/files/lib/rumai/ixp/transport_rb.html +75 -0
- data/doc/api/files/lib/rumai/ixp_rb.html +69 -0
- data/doc/api/files/lib/rumai/wm_rb.html +77 -0
- data/doc/api/files/lib/rumai_rb.html +65 -0
- data/doc/api/i/arrows.png +0 -0
- data/doc/api/i/results_bg.png +0 -0
- data/doc/api/i/tree_bg.png +0 -0
- data/doc/api/index.html +14 -18
- data/doc/api/js/jquery-1.3.2.min.js +19 -0
- data/doc/api/js/jquery-effect.js +593 -0
- data/doc/api/js/main.js +22 -0
- data/doc/api/js/searchdoc.js +605 -0
- data/doc/api/panel/index.html +63 -0
- data/doc/api/panel/search_index.js +1 -0
- data/doc/api/panel/tree.js +1 -0
- data/doc/history.erb +41 -16
- data/doc/index.erb +14 -11
- data/doc/index.xhtml +519 -846
- data/doc/intro.erb +33 -32
- data/doc/setup.erb +14 -13
- data/doc/usage.erb +69 -35
- data/lib/rumai.rb +13 -5
- data/lib/rumai/fs.rb +71 -27
- data/lib/rumai/ixp.rb +4 -0
- data/lib/rumai/ixp/message.rb +178 -81
- data/lib/rumai/ixp/transport.rb +144 -91
- data/lib/rumai/wm.rb +717 -593
- data/rakefile +14 -0
- data/test/rumai/ixp/message.rb +42 -54
- metadata +110 -89
- data/Rakefile +0 -8
- data/doc/api/IO.html +0 -53
- data/doc/api/Integer.html +0 -102
- data/doc/api/Object.html +0 -23
- data/doc/api/Rumai.html +0 -1218
- data/doc/api/Rumai/Area.html +0 -1088
- data/doc/api/Rumai/Chain.html +0 -230
- data/doc/api/Rumai/Client.html +0 -1264
- data/doc/api/Rumai/ClientContainer.html +0 -227
- data/doc/api/Rumai/ExportInstMethods.html +0 -115
- data/doc/api/Rumai/IXP.html +0 -23
- data/doc/api/Rumai/IXP/Agent.html +0 -1222
- data/doc/api/Rumai/IXP/Agent/FidStream.html +0 -602
- data/doc/api/Rumai/IXP/Agent/RangedPool.html +0 -263
- data/doc/api/Rumai/IXP/Error.html +0 -32
- data/doc/api/Rumai/IXP/Fcall.html +0 -398
- data/doc/api/Rumai/IXP/Qid.html +0 -99
- data/doc/api/Rumai/IXP/Rattach.html +0 -71
- data/doc/api/Rumai/IXP/Rauth.html +0 -71
- data/doc/api/Rumai/IXP/Rclunk.html +0 -71
- data/doc/api/Rumai/IXP/Rcreate.html +0 -71
- data/doc/api/Rumai/IXP/Rerror.html +0 -71
- data/doc/api/Rumai/IXP/Rflush.html +0 -71
- data/doc/api/Rumai/IXP/Ropen.html +0 -71
- data/doc/api/Rumai/IXP/Rread.html +0 -71
- data/doc/api/Rumai/IXP/Rremove.html +0 -71
- data/doc/api/Rumai/IXP/Rstat.html +0 -71
- data/doc/api/Rumai/IXP/Rversion.html +0 -71
- data/doc/api/Rumai/IXP/Rwalk.html +0 -71
- data/doc/api/Rumai/IXP/Rwrite.html +0 -71
- data/doc/api/Rumai/IXP/Rwstat.html +0 -71
- data/doc/api/Rumai/IXP/Stat.html +0 -188
- data/doc/api/Rumai/IXP/Stream.html +0 -112
- data/doc/api/Rumai/IXP/Struct.html +0 -348
- data/doc/api/Rumai/IXP/Struct/ClassField.html +0 -177
- data/doc/api/Rumai/IXP/Struct/Field.html +0 -549
- data/doc/api/Rumai/IXP/Struct/Field/CounteeField.html +0 -175
- data/doc/api/Rumai/IXP/Struct/Field/CounterField.html +0 -95
- data/doc/api/Rumai/IXP/Struct/Integer8Field.html +0 -181
- data/doc/api/Rumai/IXP/Struct/StringField.html +0 -128
- data/doc/api/Rumai/IXP/Tattach.html +0 -71
- data/doc/api/Rumai/IXP/Tauth.html +0 -71
- data/doc/api/Rumai/IXP/Tclunk.html +0 -71
- data/doc/api/Rumai/IXP/Tcreate.html +0 -71
- data/doc/api/Rumai/IXP/Terror.html +0 -156
- data/doc/api/Rumai/IXP/Tflush.html +0 -71
- data/doc/api/Rumai/IXP/Topen.html +0 -113
- data/doc/api/Rumai/IXP/Tread.html +0 -71
- data/doc/api/Rumai/IXP/Tremove.html +0 -71
- data/doc/api/Rumai/IXP/Tstat.html +0 -71
- data/doc/api/Rumai/IXP/Tversion.html +0 -83
- data/doc/api/Rumai/IXP/Twalk.html +0 -71
- data/doc/api/Rumai/IXP/Twrite.html +0 -71
- data/doc/api/Rumai/IXP/Twstat.html +0 -71
- data/doc/api/Rumai/Node.html +0 -1139
- data/doc/api/Rumai/View.html +0 -1280
- data/doc/api/Rumai/WidgetImpl.html +0 -196
- data/doc/api/Rumai/WidgetNode.html +0 -184
- data/doc/api/String.html +0 -180
- data/doc/api/StringIO.html +0 -53
- data/doc/api/Time.html +0 -175
- data/doc/api/all-methods.html +0 -1436
- data/doc/api/all-namespaces.html +0 -140
- data/doc/api/app.js +0 -18
- data/doc/api/jquery.js +0 -11
- data/doc/api/readme.html +0 -38
- data/doc/api/style.css +0 -68
- data/doc/api/syntax_highlight.css +0 -21
- data/doc/theory.erb +0 -3
data/lib/rumai/ixp/transport.rb
CHANGED
@@ -1,31 +1,37 @@
|
|
1
1
|
# Transport layer for 9P2000 protocol.
|
2
|
+
#--
|
3
|
+
# Copyright 2007 Suraj N. Kurapati
|
4
|
+
# See the LICENSE file for details.
|
5
|
+
#++
|
2
6
|
|
3
7
|
require 'rumai/ixp/message'
|
4
8
|
require 'thread' # for Mutex
|
5
9
|
|
6
10
|
module Rumai
|
7
11
|
module IXP
|
12
|
+
##
|
8
13
|
# A thread-safe proxy that multiplexes many
|
9
14
|
# threads onto a single 9P2000 connection.
|
15
|
+
#
|
10
16
|
class Agent
|
11
17
|
attr_reader :msize
|
12
18
|
|
13
|
-
def initialize
|
14
|
-
@stream =
|
15
|
-
@
|
16
|
-
@
|
19
|
+
def initialize stream
|
20
|
+
@stream = stream
|
21
|
+
@send_lock = Mutex.new
|
22
|
+
@recv_bays = Hash.new {|h,k| h[k] = Queue.new } # tag => Queue(message)
|
17
23
|
|
18
24
|
# background thread which continuously receives
|
19
25
|
# and dispatches messages from the 9P2000 server
|
20
26
|
Thread.new do
|
21
27
|
while true
|
22
28
|
msg = Fcall.from_9p @stream
|
23
|
-
@
|
29
|
+
@recv_bays[msg.tag] << msg
|
24
30
|
end
|
25
31
|
end.priority = -1
|
26
32
|
|
27
|
-
@
|
28
|
-
@
|
33
|
+
@tag_pool = RangedPool.new(0...BYTE2_MASK)
|
34
|
+
@fid_pool = RangedPool.new(0...BYTE4_MASK)
|
29
35
|
|
30
36
|
# establish connection with 9P2000 server
|
31
37
|
req = Tversion.new(
|
@@ -42,23 +48,25 @@ module Rumai
|
|
42
48
|
@msize = rsp.msize
|
43
49
|
|
44
50
|
# authenticate the connection (not necessary for wmii)
|
45
|
-
@
|
51
|
+
@auth_fid = Fcall::NOFID
|
46
52
|
|
47
53
|
# attach to filesystem root
|
48
|
-
@
|
49
|
-
attach @
|
54
|
+
@root_fid = @fid_pool.obtain
|
55
|
+
attach @root_fid, @auth_fid
|
50
56
|
end
|
51
57
|
|
58
|
+
##
|
52
59
|
# A finite, thread-safe pool of range members.
|
60
|
+
#
|
53
61
|
class RangedPool
|
54
62
|
# how many new members should be added
|
55
63
|
# to the pool when the pool is empty?
|
56
64
|
FILL_RATE = 10
|
57
65
|
|
58
|
-
def initialize
|
59
|
-
@pos =
|
60
|
-
@lim =
|
61
|
-
@lim = @lim.succ unless
|
66
|
+
def initialize range
|
67
|
+
@pos = range.first
|
68
|
+
@lim = range.last
|
69
|
+
@lim = @lim.succ unless range.exclude_end?
|
62
70
|
|
63
71
|
@pool = Queue.new
|
64
72
|
end
|
@@ -88,33 +96,34 @@ module Rumai
|
|
88
96
|
|
89
97
|
# Marks the given member as being unoccupied so
|
90
98
|
# that it may be occupied again in the future.
|
91
|
-
def release
|
92
|
-
@pool <<
|
99
|
+
def release member
|
100
|
+
@pool << member
|
93
101
|
end
|
94
102
|
end
|
95
103
|
|
104
|
+
##
|
96
105
|
# Sends the given message (Rumai::IXP::Fcall) and returns its response.
|
97
106
|
#
|
98
107
|
# This method allows you to perform a 9P2000 transaction without
|
99
108
|
# worrying about the details of tag collisions and thread safety.
|
100
109
|
#
|
101
|
-
def talk
|
110
|
+
def talk request
|
102
111
|
# send the request
|
103
|
-
tag = @
|
104
|
-
bay = @
|
112
|
+
tag = @tag_pool.obtain
|
113
|
+
bay = @recv_bays[tag]
|
105
114
|
|
106
|
-
|
107
|
-
output =
|
108
|
-
@
|
115
|
+
request.tag = tag
|
116
|
+
output = request.to_9p
|
117
|
+
@send_lock.synchronize do
|
109
118
|
@stream << output
|
110
119
|
end
|
111
120
|
|
112
121
|
# receive the response
|
113
122
|
response = bay.shift
|
114
|
-
@
|
123
|
+
@tag_pool.release tag
|
115
124
|
|
116
125
|
if response.is_a? Rerror
|
117
|
-
raise Error, "#{response.ename.inspect} in response to #{
|
126
|
+
raise Error, "#{response.ename.inspect} in response to #{request.inspect}"
|
118
127
|
else
|
119
128
|
return response
|
120
129
|
end
|
@@ -127,32 +136,36 @@ module Rumai
|
|
127
136
|
'+' => Topen::ORDWR,
|
128
137
|
}
|
129
138
|
|
139
|
+
##
|
130
140
|
# Converts the given mode string into an integer.
|
131
|
-
|
132
|
-
|
133
|
-
|
141
|
+
#
|
142
|
+
def MODES.parse mode
|
143
|
+
if mode.respond_to? :split
|
144
|
+
mode.split(//).inject(0) {|m,c| m | self[c].to_i }
|
134
145
|
else
|
135
|
-
|
146
|
+
mode.to_i
|
136
147
|
end
|
137
148
|
end
|
138
149
|
|
150
|
+
##
|
139
151
|
# Opens the given path for I/O access through a FidStream
|
140
152
|
# object. If a block is given, it is invoked with a
|
141
153
|
# FidStream object and the stream is closed afterwards.
|
142
154
|
#
|
143
155
|
# See File::open in the Ruby documentation.
|
144
|
-
|
145
|
-
|
156
|
+
#
|
157
|
+
def open path, mode = 'r' # :yields: FidStream
|
158
|
+
mode = MODES.parse(mode)
|
146
159
|
|
147
160
|
# open the file
|
148
|
-
|
161
|
+
path_fid = walk(path)
|
149
162
|
|
150
163
|
talk Topen.new(
|
151
|
-
:fid =>
|
164
|
+
:fid => path_fid,
|
152
165
|
:mode => mode
|
153
166
|
)
|
154
167
|
|
155
|
-
stream = FidStream.new(self,
|
168
|
+
stream = FidStream.new(self, path_fid, @msize)
|
156
169
|
|
157
170
|
# return the file stream
|
158
171
|
if block_given?
|
@@ -166,8 +179,11 @@ module Rumai
|
|
166
179
|
end
|
167
180
|
end
|
168
181
|
|
182
|
+
##
|
169
183
|
# Encapsulates I/O access over a file handle (fid).
|
170
|
-
#
|
184
|
+
#
|
185
|
+
# NOTE: this class is NOT thread-safe.
|
186
|
+
#
|
171
187
|
class FidStream
|
172
188
|
attr_reader :fid, :stat
|
173
189
|
|
@@ -177,22 +193,26 @@ module Rumai
|
|
177
193
|
attr_accessor :pos
|
178
194
|
alias tell pos
|
179
195
|
|
180
|
-
def initialize
|
181
|
-
@agent =
|
182
|
-
@fid =
|
183
|
-
@msize =
|
184
|
-
@stat = @agent.stat_fid
|
196
|
+
def initialize agent, path_fid, message_size
|
197
|
+
@agent = agent
|
198
|
+
@fid = path_fid
|
199
|
+
@msize = message_size
|
200
|
+
@stat = @agent.stat_fid(@fid)
|
185
201
|
@closed = false
|
186
202
|
rewind
|
187
203
|
end
|
188
204
|
|
205
|
+
##
|
189
206
|
# Rewinds the stream to the beginning.
|
207
|
+
#
|
190
208
|
def rewind
|
191
209
|
@pos = 0
|
192
210
|
@eof = false
|
193
211
|
end
|
194
212
|
|
213
|
+
##
|
195
214
|
# Closes this stream.
|
215
|
+
#
|
196
216
|
def close
|
197
217
|
unless @closed
|
198
218
|
@agent.clunk @fid
|
@@ -201,22 +221,27 @@ module Rumai
|
|
201
221
|
end
|
202
222
|
end
|
203
223
|
|
224
|
+
##
|
204
225
|
# Returns true if this stream is closed.
|
226
|
+
#
|
205
227
|
def closed?
|
206
228
|
@closed
|
207
229
|
end
|
208
230
|
|
231
|
+
##
|
209
232
|
# Reads some data from this stream at the current position.
|
210
233
|
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
234
|
+
# [partial]
|
235
|
+
# When false, the entire content of
|
236
|
+
# this stream is read and returned.
|
237
|
+
#
|
238
|
+
# When true, the maximum amount of content that can fit
|
239
|
+
# inside a single 9P2000 message is read and returned.
|
215
240
|
#
|
216
241
|
# If this stream corresponds to a directory, then an Array of
|
217
242
|
# Stat (one for each file in the directory) will be returned.
|
218
243
|
#
|
219
|
-
def read
|
244
|
+
def read partial = false
|
220
245
|
raise 'cannot read from a closed stream' if @closed
|
221
246
|
|
222
247
|
content = ''
|
@@ -231,7 +256,7 @@ module Rumai
|
|
231
256
|
content << rsp.data
|
232
257
|
count = rsp.count
|
233
258
|
@pos += count
|
234
|
-
end until @eof = count.zero? or
|
259
|
+
end until @eof = count.zero? or partial
|
235
260
|
|
236
261
|
# the content of a directory is a sequence
|
237
262
|
# of Stat for all files in that directory
|
@@ -247,12 +272,14 @@ module Rumai
|
|
247
272
|
content
|
248
273
|
end
|
249
274
|
|
275
|
+
##
|
250
276
|
# Writes the given content at the current position in this stream.
|
251
|
-
|
277
|
+
#
|
278
|
+
def write content
|
252
279
|
raise 'closed streams cannot be written to' if @closed
|
253
280
|
raise 'directories cannot be written to' if @stat.directory?
|
254
281
|
|
255
|
-
data =
|
282
|
+
data = content.to_s
|
256
283
|
limit = data.length + @pos
|
257
284
|
|
258
285
|
while @pos < limit
|
@@ -273,115 +300,141 @@ module Rumai
|
|
273
300
|
alias << write
|
274
301
|
end
|
275
302
|
|
303
|
+
##
|
276
304
|
# Returns the content of the file/directory at the given path.
|
277
|
-
|
278
|
-
|
279
|
-
|
305
|
+
#
|
306
|
+
def read path, *args
|
307
|
+
open path do |f|
|
308
|
+
f.read(*args)
|
280
309
|
end
|
281
310
|
end
|
282
311
|
|
312
|
+
##
|
283
313
|
# Returns the names of all files inside the directory whose path is given.
|
284
|
-
|
285
|
-
|
286
|
-
|
314
|
+
#
|
315
|
+
def entries path
|
316
|
+
unless stat(path).directory?
|
317
|
+
raise ArgumentError, "#{path.inspect} is not a directory"
|
287
318
|
end
|
288
319
|
|
289
|
-
read(
|
320
|
+
read(path).map! {|t| t.name}
|
290
321
|
end
|
291
322
|
|
323
|
+
##
|
292
324
|
# Returns the content of the file/directory at the given path.
|
293
|
-
|
294
|
-
|
295
|
-
|
325
|
+
#
|
326
|
+
def write path, content
|
327
|
+
open path, 'w' do |f|
|
328
|
+
f << content
|
296
329
|
end
|
297
330
|
end
|
298
331
|
|
332
|
+
##
|
299
333
|
# Creates a new file at the given path that is accessible using
|
300
334
|
# the given modes for a user having the given permission bits.
|
301
|
-
|
302
|
-
|
303
|
-
|
335
|
+
#
|
336
|
+
def create path, mode = 'rw', perm = 0644
|
337
|
+
prefix = File.dirname(path)
|
338
|
+
target = File.basename(path)
|
304
339
|
|
305
|
-
mode = MODES.parse(
|
340
|
+
mode = MODES.parse(mode)
|
306
341
|
|
307
|
-
with_fid do |
|
308
|
-
walk_fid
|
342
|
+
with_fid do |prefix_fid|
|
343
|
+
walk_fid prefix_fid, prefix
|
309
344
|
|
310
345
|
# create the file
|
311
346
|
talk Tcreate.new(
|
312
|
-
:fid =>
|
347
|
+
:fid => prefix_fid,
|
313
348
|
:name => target,
|
314
|
-
:perm =>
|
349
|
+
:perm => perm,
|
315
350
|
:mode => mode
|
316
351
|
)
|
317
352
|
end
|
318
353
|
end
|
319
354
|
|
355
|
+
##
|
320
356
|
# Deletes the file at the given path.
|
321
|
-
|
322
|
-
|
323
|
-
|
357
|
+
#
|
358
|
+
def remove path
|
359
|
+
path_fid = walk(path)
|
360
|
+
remove_fid path_fid # remove also does clunk
|
324
361
|
end
|
325
362
|
|
363
|
+
##
|
326
364
|
# Deletes the file corresponding to the
|
327
365
|
# given FID and clunks the given FID.
|
328
|
-
|
329
|
-
|
366
|
+
#
|
367
|
+
def remove_fid path_fid
|
368
|
+
talk Tremove.new(:fid => path_fid)
|
330
369
|
end
|
331
370
|
|
371
|
+
##
|
332
372
|
# Returns information about the file at the given path.
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
373
|
+
#
|
374
|
+
def stat path
|
375
|
+
with_fid do |path_fid|
|
376
|
+
walk_fid path_fid, path
|
377
|
+
stat_fid path_fid
|
337
378
|
end
|
338
379
|
end
|
339
380
|
|
381
|
+
##
|
340
382
|
# Returns information about the file referenced by the given FID.
|
341
|
-
|
342
|
-
|
383
|
+
#
|
384
|
+
def stat_fid path_fid
|
385
|
+
req = Tstat.new(:fid => path_fid)
|
343
386
|
rsp = talk(req)
|
344
387
|
rsp.stat
|
345
388
|
end
|
346
389
|
|
390
|
+
##
|
347
391
|
# Returns an FID corresponding to the given path.
|
348
|
-
|
349
|
-
|
350
|
-
|
392
|
+
#
|
393
|
+
def walk path
|
394
|
+
fid = @fid_pool.obtain
|
395
|
+
walk_fid fid, path
|
351
396
|
fid
|
352
397
|
end
|
353
398
|
|
399
|
+
##
|
354
400
|
# Associates the given FID to the given path.
|
355
|
-
|
401
|
+
#
|
402
|
+
def walk_fid path_fid, path
|
356
403
|
talk Twalk.new(
|
357
|
-
:fid => @
|
358
|
-
:newfid =>
|
359
|
-
:wname =>
|
404
|
+
:fid => @root_fid,
|
405
|
+
:newfid => path_fid,
|
406
|
+
:wname => path.to_s.split(%r{/+}).reject {|s| s.empty? }
|
360
407
|
)
|
361
408
|
end
|
362
409
|
|
410
|
+
##
|
363
411
|
# Associates the given FID with the FS root.
|
364
|
-
|
412
|
+
#
|
413
|
+
def attach root_fid, auth_fid = Fcall::NOFID, auth_name = ENV['USER']
|
365
414
|
talk Tattach.new(
|
366
|
-
:fid =>
|
367
|
-
:afid =>
|
415
|
+
:fid => root_fid,
|
416
|
+
:afid => auth_fid,
|
368
417
|
:uname => ENV['USER'],
|
369
|
-
:aname =>
|
418
|
+
:aname => auth_name
|
370
419
|
)
|
371
420
|
end
|
372
421
|
|
422
|
+
##
|
373
423
|
# Retires the given FID from use.
|
374
|
-
|
375
|
-
|
376
|
-
|
424
|
+
#
|
425
|
+
def clunk fid
|
426
|
+
talk Tclunk.new(:fid => fid)
|
427
|
+
@fid_pool.release fid
|
377
428
|
end
|
378
429
|
|
379
430
|
private
|
380
431
|
|
432
|
+
##
|
381
433
|
# Invokes the given block with a temporary FID.
|
434
|
+
#
|
382
435
|
def with_fid # :yields: fid
|
383
436
|
begin
|
384
|
-
fid = @
|
437
|
+
fid = @fid_pool.obtain
|
385
438
|
yield fid
|
386
439
|
ensure
|
387
440
|
clunk fid
|