169
170
171
172
173
174
175
176
177
178
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
209
210
211
212
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
|
# File 'lib/suzuna.rb', line 169
def self.mainloop(unitobj, unit)
ioc = IOCTL::IOReq.new
ioc.start.version = G_GATE_VERSION
ioc.start.unit = unit
bufsize = unitobj.sectorsize
buf = String.alloc(bufsize)
ioc.start.data = buf.to_ptr
while true
while true
ioc.start.data = buf.to_ptr
ioc.start.length = buf.bytesize
ioc.start.error = 0
begin
ioc.start.post
rescue Errno::ENXIO
raise DestroyedGate, "/dev/ggate#{unit}"
end
case ioc.start.error
when Errno::NOERROR::Errno
when Errno::ECANCELED::Errno, Errno::ENXIO::Errno
raise DestroyedGate, "/dev/ggate#{unit}"
when Errno::ENOMEM::Errno
buf.resize(bufsize = ioc.start.length)
unless buf.bytesize == bufsize
raise Errno::ENOMEM, <<-EOM.chomp
#{G_GATE_CTL_NAME} (require size = #{bufsize}, but allocated size = #{buf.bytesize})
EOM
end
break
else
raise SystemCallError.new("#{G_GATE_CTL_NAME} (ioctl)", ioc.start.error)
end
catch(:break) do
begin
case ioc.start.cmd
when BIO_READ
if ioc.start.length > bufsize
buf.resize(bufsize = ioc.start.length)
unless buf.bytesize == bufsize
ioc.done.error = Errno::ENOMEM::Errno
throw :break
end
end
ioc.done.error = err2code(unitobj.read(ioc.start.offset, ioc.start.length, buf))
ioc.done.data = buf.to_ptr
when BIO_DELETE
ioc.done.error = err2code(unitobj.delete(ioc.start.offset, ioc.start.length))
when BIO_WRITE
buf.resize(ioc.start.length)
ioc.done.error = err2code(unitobj.write(ioc.start.offset, buf))
buf.resize(bufsize)
ioc.done.data = buf.to_ptr
else
ioc.done.error = Errno::EOPNOTSUPP::Errno
end
rescue BasicObject
ioc.done.error = Errno::EFAULT::Errno
raise
ensure
ioc.done.post
end
end
end
end
raise Exception, "!!BUG!! - SHALL NOT REACHED HERE!"
end
|