Revision d50ed8d4 snf-pithos-tools/pithos/tools/lib/fuse.py
b/snf-pithos-tools/pithos/tools/lib/fuse.py | ||
---|---|---|
1 | 1 |
# Copyright (c) 2008 Giorgos Verigakis <verigak@gmail.com> |
2 |
#
|
|
2 |
# |
|
3 | 3 |
# Permission to use, copy, modify, and distribute this software for any |
4 | 4 |
# purpose with or without fee is hereby granted, provided that the above |
5 | 5 |
# copyright notice and this permission notice appear in all copies. |
6 |
#
|
|
6 |
# |
|
7 | 7 |
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
8 | 8 |
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
9 | 9 |
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
... | ... | |
27 | 27 |
class c_timespec(Structure): |
28 | 28 |
_fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)] |
29 | 29 |
|
30 |
|
|
30 | 31 |
class c_utimbuf(Structure): |
31 | 32 |
_fields_ = [('actime', c_timespec), ('modtime', c_timespec)] |
32 | 33 |
|
34 |
|
|
33 | 35 |
class c_stat(Structure): |
34 | 36 |
pass # Platform dependent |
35 | 37 |
|
36 | 38 |
_system = system() |
37 | 39 |
if _system in ('Darwin', 'FreeBSD'): |
38 |
_libiconv = CDLL(find_library("iconv"), RTLD_GLOBAL) # libfuse dependency |
|
40 |
_libiconv = CDLL( |
|
41 |
find_library("iconv"), RTLD_GLOBAL) # libfuse dependency |
|
39 | 42 |
ENOTSUP = 45 |
40 | 43 |
c_dev_t = c_int32 |
41 | 44 |
c_fsblkcnt_t = c_ulong |
... | ... | |
46 | 49 |
c_pid_t = c_int32 |
47 | 50 |
c_uid_t = c_uint32 |
48 | 51 |
setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), |
49 |
c_size_t, c_int, c_uint32) |
|
52 |
c_size_t, c_int, c_uint32)
|
|
50 | 53 |
getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), |
51 |
c_size_t, c_uint32) |
|
54 |
c_size_t, c_uint32)
|
|
52 | 55 |
c_stat._fields_ = [ |
53 | 56 |
('st_dev', c_dev_t), |
54 | 57 |
('st_ino', c_uint32), |
... | ... | |
73 | 76 |
c_off_t = c_longlong |
74 | 77 |
c_pid_t = c_int |
75 | 78 |
c_uid_t = c_uint |
76 |
setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int) |
|
77 |
getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t) |
|
78 |
|
|
79 |
setxattr_t = CFUNCTYPE( |
|
80 |
c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int) |
|
81 |
getxattr_t = CFUNCTYPE( |
|
82 |
c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t) |
|
83 |
|
|
79 | 84 |
_machine = machine() |
80 | 85 |
if _machine == 'x86_64': |
81 | 86 |
c_stat._fields_ = [ |
... | ... | |
146 | 151 |
if _system == 'FreeBSD': |
147 | 152 |
c_fsblkcnt_t = c_uint64 |
148 | 153 |
c_fsfilcnt_t = c_uint64 |
149 |
setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int) |
|
150 |
getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t) |
|
154 |
setxattr_t = CFUNCTYPE( |
|
155 |
c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int) |
|
156 |
getxattr_t = CFUNCTYPE( |
|
157 |
c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t) |
|
158 |
|
|
151 | 159 |
class c_statvfs(Structure): |
152 | 160 |
_fields_ = [ |
153 | 161 |
('f_bavail', c_fsblkcnt_t), |
... | ... | |
160 | 168 |
('f_flag', c_ulong), |
161 | 169 |
('f_frsize', c_ulong)] |
162 | 170 |
|
171 |
|
|
163 | 172 |
class fuse_file_info(Structure): |
164 | 173 |
_fields_ = [ |
165 | 174 |
('flags', c_int), |
... | ... | |
172 | 181 |
('fh', c_uint64), |
173 | 182 |
('lock_owner', c_uint64)] |
174 | 183 |
|
184 |
|
|
175 | 185 |
class fuse_context(Structure): |
176 | 186 |
_fields_ = [ |
177 | 187 |
('fuse', c_voidp), |
... | ... | |
180 | 190 |
('pid', c_pid_t), |
181 | 191 |
('private_data', c_voidp)] |
182 | 192 |
|
193 |
|
|
183 | 194 |
class fuse_operations(Structure): |
184 | 195 |
_fields_ = [ |
185 | 196 |
('getattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat))), |
... | ... | |
198 | 209 |
('utime', c_voidp), # Deprecated, use utimens |
199 | 210 |
('open', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))), |
200 | 211 |
('read', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t, |
201 |
POINTER(fuse_file_info))), |
|
202 |
('write', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t, |
|
212 |
POINTER(fuse_file_info))), |
|
213 |
( |
|
214 |
'write', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t, |
|
203 | 215 |
POINTER(fuse_file_info))), |
204 | 216 |
('statfs', CFUNCTYPE(c_int, c_char_p, POINTER(c_statvfs))), |
205 | 217 |
('flush', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))), |
... | ... | |
210 | 222 |
('listxattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t)), |
211 | 223 |
('removexattr', CFUNCTYPE(c_int, c_char_p, c_char_p)), |
212 | 224 |
('opendir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))), |
213 |
('readdir', CFUNCTYPE(c_int, c_char_p, c_voidp, CFUNCTYPE(c_int, c_voidp, |
|
214 |
c_char_p, POINTER(c_stat), c_off_t), c_off_t, POINTER(fuse_file_info))), |
|
225 |
( |
|
226 |
'readdir', CFUNCTYPE(c_int, c_char_p, c_voidp, CFUNCTYPE(c_int, c_voidp, |
|
227 |
c_char_p, POINTER( |
|
228 |
c_stat), c_off_t), c_off_t, POINTER(fuse_file_info))), |
|
215 | 229 |
('releasedir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))), |
216 |
('fsyncdir', CFUNCTYPE(c_int, c_char_p, c_int, POINTER(fuse_file_info))), |
|
230 |
('fsyncdir', CFUNCTYPE(c_int, c_char_p, c_int, POINTER( |
|
231 |
fuse_file_info))), |
|
217 | 232 |
('init', CFUNCTYPE(c_voidp, c_voidp)), |
218 | 233 |
('destroy', CFUNCTYPE(c_voidp, c_voidp)), |
219 | 234 |
('access', CFUNCTYPE(c_int, c_char_p, c_int)), |
220 |
('create', CFUNCTYPE(c_int, c_char_p, c_mode_t, POINTER(fuse_file_info))), |
|
221 |
('ftruncate', CFUNCTYPE(c_int, c_char_p, c_off_t, POINTER(fuse_file_info))), |
|
235 |
('create', CFUNCTYPE(c_int, c_char_p, c_mode_t, POINTER( |
|
236 |
fuse_file_info))), |
|
237 |
('ftruncate', CFUNCTYPE(c_int, c_char_p, c_off_t, POINTER( |
|
238 |
fuse_file_info))), |
|
222 | 239 |
('fgetattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat), |
223 |
POINTER(fuse_file_info))), |
|
224 |
('lock', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info), c_int, c_voidp)), |
|
240 |
POINTER(fuse_file_info))), |
|
241 |
('lock', CFUNCTYPE( |
|
242 |
c_int, c_char_p, POINTER(fuse_file_info), c_int, c_voidp)), |
|
225 | 243 |
('utimens', CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))), |
226 | 244 |
('bmap', CFUNCTYPE(c_int, c_char_p, c_size_t, POINTER(c_ulonglong)))] |
227 | 245 |
|
... | ... | |
229 | 247 |
def time_of_timespec(ts): |
230 | 248 |
return ts.tv_sec + ts.tv_nsec / 10 ** 9 |
231 | 249 |
|
250 |
|
|
232 | 251 |
def set_st_attrs(st, attrs): |
233 | 252 |
for key, val in attrs.items(): |
234 | 253 |
if key in ('st_atime', 'st_mtime', 'st_ctime'): |
... | ... | |
262 | 281 |
"""This class is the lower level interface and should not be subclassed |
263 | 282 |
under normal use. Its methods are called by fuse. |
264 | 283 |
Assumes API version 2.6 or later.""" |
265 |
|
|
284 |
|
|
266 | 285 |
def __init__(self, operations, mountpoint, raw_fi=False, **kwargs): |
267 | 286 |
"""Setting raw_fi to True will cause FUSE to pass the fuse_file_info |
268 | 287 |
class as is to Operations, instead of just the fh field. |
269 | 288 |
This gives you access to direct_io, keep_cache, etc.""" |
270 |
|
|
289 |
|
|
271 | 290 |
self.operations = operations |
272 | 291 |
self.raw_fi = raw_fi |
273 | 292 |
args = ['fuse'] |
... | ... | |
280 | 299 |
kwargs.setdefault('fsname', operations.__class__.__name__) |
281 | 300 |
args.append('-o') |
282 | 301 |
args.append(','.join(key if val == True else '%s=%s' % (key, val) |
283 |
for key, val in kwargs.items())) |
|
302 |
for key, val in kwargs.items()))
|
|
284 | 303 |
args.append(mountpoint) |
285 | 304 |
argv = (c_char_p * len(args))(*args) |
286 |
|
|
305 |
|
|
287 | 306 |
fuse_ops = fuse_operations() |
288 | 307 |
for name, prototype in fuse_operations._fields_: |
289 | 308 |
if prototype != c_voidp and getattr(operations, name, None): |
290 | 309 |
op = partial(self._wrapper_, getattr(self, name)) |
291 | 310 |
setattr(fuse_ops, name, prototype(op)) |
292 | 311 |
err = _libfuse.fuse_main_real(len(args), argv, pointer(fuse_ops), |
293 |
sizeof(fuse_ops), None)
|
|
312 |
sizeof(fuse_ops), None)
|
|
294 | 313 |
del self.operations # Invoke the destructor |
295 | 314 |
if err: |
296 | 315 |
raise RuntimeError(err) |
297 |
|
|
316 |
|
|
298 | 317 |
def _wrapper_(self, func, *args, **kwargs): |
299 | 318 |
"""Decorator for the methods that follow""" |
300 | 319 |
try: |
... | ... | |
304 | 323 |
except: |
305 | 324 |
print_exc() |
306 | 325 |
return -EFAULT |
307 |
|
|
326 |
|
|
308 | 327 |
def getattr(self, path, buf): |
309 | 328 |
return self.fgetattr(path, buf, None) |
310 |
|
|
329 |
|
|
311 | 330 |
def readlink(self, path, buf, bufsize): |
312 | 331 |
ret = self.operations('readlink', path) |
313 | 332 |
data = create_string_buffer(ret[:bufsize - 1]) |
314 | 333 |
memmove(buf, data, len(data)) |
315 | 334 |
return 0 |
316 |
|
|
335 |
|
|
317 | 336 |
def mknod(self, path, mode, dev): |
318 | 337 |
return self.operations('mknod', path, mode, dev) |
319 |
|
|
338 |
|
|
320 | 339 |
def mkdir(self, path, mode): |
321 | 340 |
return self.operations('mkdir', path, mode) |
322 |
|
|
341 |
|
|
323 | 342 |
def unlink(self, path): |
324 | 343 |
return self.operations('unlink', path) |
325 |
|
|
344 |
|
|
326 | 345 |
def rmdir(self, path): |
327 | 346 |
return self.operations('rmdir', path) |
328 |
|
|
347 |
|
|
329 | 348 |
def symlink(self, source, target): |
330 | 349 |
return self.operations('symlink', target, source) |
331 |
|
|
350 |
|
|
332 | 351 |
def rename(self, old, new): |
333 | 352 |
return self.operations('rename', old, new) |
334 |
|
|
353 |
|
|
335 | 354 |
def link(self, source, target): |
336 | 355 |
return self.operations('link', target, source) |
337 |
|
|
356 |
|
|
338 | 357 |
def chmod(self, path, mode): |
339 | 358 |
return self.operations('chmod', path, mode) |
340 |
|
|
359 |
|
|
341 | 360 |
def chown(self, path, uid, gid): |
342 | 361 |
# Check if any of the arguments is a -1 that has overflowed |
343 | 362 |
if c_uid_t(uid + 1).value == 0: |
... | ... | |
345 | 364 |
if c_gid_t(gid + 1).value == 0: |
346 | 365 |
gid = -1 |
347 | 366 |
return self.operations('chown', path, uid, gid) |
348 |
|
|
367 |
|
|
349 | 368 |
def truncate(self, path, length): |
350 | 369 |
return self.operations('truncate', path, length) |
351 |
|
|
370 |
|
|
352 | 371 |
def open(self, path, fip): |
353 | 372 |
fi = fip.contents |
354 | 373 |
if self.raw_fi: |
... | ... | |
356 | 375 |
else: |
357 | 376 |
fi.fh = self.operations('open', path, fi.flags) |
358 | 377 |
return 0 |
359 |
|
|
378 |
|
|
360 | 379 |
def read(self, path, buf, size, offset, fip): |
361 | 380 |
fh = fip.contents if self.raw_fi else fip.contents.fh |
362 | 381 |
ret = self.operations('read', path, size, offset, fh) |
... | ... | |
365 | 384 |
data = create_string_buffer(ret[:size], size) |
366 | 385 |
memmove(buf, data, size) |
367 | 386 |
return size |
368 |
|
|
387 |
|
|
369 | 388 |
def write(self, path, buf, size, offset, fip): |
370 | 389 |
data = string_at(buf, size) |
371 | 390 |
fh = fip.contents if self.raw_fi else fip.contents.fh |
372 | 391 |
return self.operations('write', path, data, offset, fh) |
373 |
|
|
392 |
|
|
374 | 393 |
def statfs(self, path, buf): |
375 | 394 |
stv = buf.contents |
376 | 395 |
attrs = self.operations('statfs', path) |
... | ... | |
378 | 397 |
if hasattr(stv, key): |
379 | 398 |
setattr(stv, key, val) |
380 | 399 |
return 0 |
381 |
|
|
400 |
|
|
382 | 401 |
def flush(self, path, fip): |
383 | 402 |
fh = fip.contents if self.raw_fi else fip.contents.fh |
384 | 403 |
return self.operations('flush', path, fh) |
385 |
|
|
404 |
|
|
386 | 405 |
def release(self, path, fip): |
387 | 406 |
fh = fip.contents if self.raw_fi else fip.contents.fh |
388 | 407 |
return self.operations('release', path, fh) |
389 |
|
|
408 |
|
|
390 | 409 |
def fsync(self, path, datasync, fip): |
391 | 410 |
fh = fip.contents if self.raw_fi else fip.contents.fh |
392 | 411 |
return self.operations('fsync', path, datasync, fh) |
393 |
|
|
412 |
|
|
394 | 413 |
def setxattr(self, path, name, value, size, options, *args): |
395 | 414 |
data = string_at(value, size) |
396 | 415 |
return self.operations('setxattr', path, name, data, options, *args) |
397 |
|
|
416 |
|
|
398 | 417 |
def getxattr(self, path, name, value, size, *args): |
399 | 418 |
ret = self.operations('getxattr', path, name, *args) |
400 | 419 |
retsize = len(ret) |
... | ... | |
404 | 423 |
return -ERANGE |
405 | 424 |
memmove(value, buf, retsize) |
406 | 425 |
return retsize |
407 |
|
|
426 |
|
|
408 | 427 |
def listxattr(self, path, namebuf, size): |
409 | 428 |
ret = self.operations('listxattr', path) |
410 | 429 |
buf = create_string_buffer('\x00'.join(ret)) if ret else '' |
... | ... | |
414 | 433 |
return -ERANGE |
415 | 434 |
memmove(namebuf, buf, bufsize) |
416 | 435 |
return bufsize |
417 |
|
|
436 |
|
|
418 | 437 |
def removexattr(self, path, name): |
419 | 438 |
return self.operations('removexattr', path, name) |
420 |
|
|
439 |
|
|
421 | 440 |
def opendir(self, path, fip): |
422 | 441 |
# Ignore raw_fi |
423 | 442 |
fip.contents.fh = self.operations('opendir', path) |
424 | 443 |
return 0 |
425 |
|
|
444 |
|
|
426 | 445 |
def readdir(self, path, buf, filler, offset, fip): |
427 | 446 |
# Ignore raw_fi |
428 | 447 |
for item in self.operations('readdir', path, fip.contents.fh): |
... | ... | |
438 | 457 |
if filler(buf, name, st, offset) != 0: |
439 | 458 |
break |
440 | 459 |
return 0 |
441 |
|
|
460 |
|
|
442 | 461 |
def releasedir(self, path, fip): |
443 | 462 |
# Ignore raw_fi |
444 | 463 |
return self.operations('releasedir', path, fip.contents.fh) |
445 |
|
|
464 |
|
|
446 | 465 |
def fsyncdir(self, path, datasync, fip): |
447 | 466 |
# Ignore raw_fi |
448 | 467 |
return self.operations('fsyncdir', path, datasync, fip.contents.fh) |
449 |
|
|
468 |
|
|
450 | 469 |
def init(self, conn): |
451 | 470 |
return self.operations('init', '/') |
452 |
|
|
471 |
|
|
453 | 472 |
def destroy(self, private_data): |
454 | 473 |
return self.operations('destroy', '/') |
455 |
|
|
474 |
|
|
456 | 475 |
def access(self, path, amode): |
457 | 476 |
return self.operations('access', path, amode) |
458 |
|
|
477 |
|
|
459 | 478 |
def create(self, path, mode, fip): |
460 | 479 |
fi = fip.contents |
461 | 480 |
if self.raw_fi: |
... | ... | |
463 | 482 |
else: |
464 | 483 |
fi.fh = self.operations('create', path, mode) |
465 | 484 |
return 0 |
466 |
|
|
485 |
|
|
467 | 486 |
def ftruncate(self, path, length, fip): |
468 | 487 |
fh = fip.contents if self.raw_fi else fip.contents.fh |
469 | 488 |
return self.operations('truncate', path, length, fh) |
470 |
|
|
489 |
|
|
471 | 490 |
def fgetattr(self, path, buf, fip): |
472 | 491 |
memset(buf, 0, sizeof(c_stat)) |
473 | 492 |
st = buf.contents |
... | ... | |
475 | 494 |
attrs = self.operations('getattr', path, fh) |
476 | 495 |
set_st_attrs(st, attrs) |
477 | 496 |
return 0 |
478 |
|
|
497 |
|
|
479 | 498 |
def lock(self, path, fip, cmd, lock): |
480 | 499 |
fh = fip.contents if self.raw_fi else fip.contents.fh |
481 | 500 |
return self.operations('lock', path, fh, cmd, lock) |
482 |
|
|
501 |
|
|
483 | 502 |
def utimens(self, path, buf): |
484 | 503 |
if buf: |
485 | 504 |
atime = time_of_timespec(buf.contents.actime) |
... | ... | |
488 | 507 |
else: |
489 | 508 |
times = None |
490 | 509 |
return self.operations('utimens', path, times) |
491 |
|
|
510 |
|
|
492 | 511 |
def bmap(self, path, blocksize, idx): |
493 | 512 |
return self.operations('bmap', path, blocksize, idx) |
494 | 513 |
|
... | ... | |
497 | 516 |
"""This class should be subclassed and passed as an argument to FUSE on |
498 | 517 |
initialization. All operations should raise a FuseOSError exception |
499 | 518 |
on error. |
500 |
|
|
519 |
|
|
501 | 520 |
When in doubt of what an operation should do, check the FUSE header |
502 | 521 |
file or the corresponding system call man page.""" |
503 |
|
|
522 |
|
|
504 | 523 |
def __call__(self, op, *args): |
505 | 524 |
if not hasattr(self, op): |
506 | 525 |
raise FuseOSError(EFAULT) |
507 | 526 |
return getattr(self, op)(*args) |
508 |
|
|
527 |
|
|
509 | 528 |
def access(self, path, amode): |
510 | 529 |
return 0 |
511 |
|
|
530 |
|
|
512 | 531 |
bmap = None |
513 |
|
|
532 |
|
|
514 | 533 |
def chmod(self, path, mode): |
515 | 534 |
raise FuseOSError(EROFS) |
516 |
|
|
535 |
|
|
517 | 536 |
def chown(self, path, uid, gid): |
518 | 537 |
raise FuseOSError(EROFS) |
519 |
|
|
538 |
|
|
520 | 539 |
def create(self, path, mode, fi=None): |
521 | 540 |
"""When raw_fi is False (default case), fi is None and create should |
522 | 541 |
return a numerical file handle. |
523 | 542 |
When raw_fi is True the file handle should be set directly by create |
524 | 543 |
and return 0.""" |
525 | 544 |
raise FuseOSError(EROFS) |
526 |
|
|
545 |
|
|
527 | 546 |
def destroy(self, path): |
528 | 547 |
"""Called on filesystem destruction. Path is always /""" |
529 | 548 |
pass |
530 |
|
|
549 |
|
|
531 | 550 |
def flush(self, path, fh): |
532 | 551 |
return 0 |
533 |
|
|
552 |
|
|
534 | 553 |
def fsync(self, path, datasync, fh): |
535 | 554 |
return 0 |
536 |
|
|
555 |
|
|
537 | 556 |
def fsyncdir(self, path, datasync, fh): |
538 | 557 |
return 0 |
539 |
|
|
558 |
|
|
540 | 559 |
def getattr(self, path, fh=None): |
541 | 560 |
"""Returns a dictionary with keys identical to the stat C structure |
542 | 561 |
of stat(2). |
... | ... | |
544 | 563 |
NOTE: There is an incombatibility between Linux and Mac OS X concerning |
545 | 564 |
st_nlink of directories. Mac OS X counts all files inside the directory, |
546 | 565 |
while Linux counts only the subdirectories.""" |
547 |
|
|
566 |
|
|
548 | 567 |
if path != '/': |
549 | 568 |
raise FuseOSError(ENOENT) |
550 | 569 |
return dict(st_mode=(S_IFDIR | 0755), st_nlink=2) |
551 |
|
|
570 |
|
|
552 | 571 |
def getxattr(self, path, name, position=0): |
553 | 572 |
raise FuseOSError(ENOTSUP) |
554 |
|
|
573 |
|
|
555 | 574 |
def init(self, path): |
556 | 575 |
"""Called on filesystem initialization. Path is always / |
557 | 576 |
Use it instead of __init__ if you start threads on initialization.""" |
558 | 577 |
pass |
559 |
|
|
578 |
|
|
560 | 579 |
def link(self, target, source): |
561 | 580 |
raise FuseOSError(EROFS) |
562 |
|
|
581 |
|
|
563 | 582 |
def listxattr(self, path): |
564 | 583 |
return [] |
565 |
|
|
584 |
|
|
566 | 585 |
lock = None |
567 |
|
|
586 |
|
|
568 | 587 |
def mkdir(self, path, mode): |
569 | 588 |
raise FuseOSError(EROFS) |
570 |
|
|
589 |
|
|
571 | 590 |
def mknod(self, path, mode, dev): |
572 | 591 |
raise FuseOSError(EROFS) |
573 |
|
|
592 |
|
|
574 | 593 |
def open(self, path, flags): |
575 | 594 |
"""When raw_fi is False (default case), open should return a numerical |
576 | 595 |
file handle. |
... | ... | |
578 | 597 |
open(self, path, fi) |
579 | 598 |
and the file handle should be set directly.""" |
580 | 599 |
return 0 |
581 |
|
|
600 |
|
|
582 | 601 |
def opendir(self, path): |
583 | 602 |
"""Returns a numerical file handle.""" |
584 | 603 |
return 0 |
585 |
|
|
604 |
|
|
586 | 605 |
def read(self, path, size, offset, fh): |
587 | 606 |
"""Returns a string containing the data requested.""" |
588 | 607 |
raise FuseOSError(EIO) |
589 |
|
|
608 |
|
|
590 | 609 |
def readdir(self, path, fh): |
591 | 610 |
"""Can return either a list of names, or a list of (name, attrs, offset) |
592 | 611 |
tuples. attrs is a dict as in getattr.""" |
593 | 612 |
return ['.', '..'] |
594 |
|
|
613 |
|
|
595 | 614 |
def readlink(self, path): |
596 | 615 |
raise FuseOSError(ENOENT) |
597 |
|
|
616 |
|
|
598 | 617 |
def release(self, path, fh): |
599 | 618 |
return 0 |
600 |
|
|
619 |
|
|
601 | 620 |
def releasedir(self, path, fh): |
602 | 621 |
return 0 |
603 |
|
|
622 |
|
|
604 | 623 |
def removexattr(self, path, name): |
605 | 624 |
raise FuseOSError(ENOTSUP) |
606 |
|
|
625 |
|
|
607 | 626 |
def rename(self, old, new): |
608 | 627 |
raise FuseOSError(EROFS) |
609 |
|
|
628 |
|
|
610 | 629 |
def rmdir(self, path): |
611 | 630 |
raise FuseOSError(EROFS) |
612 |
|
|
631 |
|
|
613 | 632 |
def setxattr(self, path, name, value, options, position=0): |
614 | 633 |
raise FuseOSError(ENOTSUP) |
615 |
|
|
634 |
|
|
616 | 635 |
def statfs(self, path): |
617 | 636 |
"""Returns a dictionary with keys identical to the statvfs C structure |
618 | 637 |
of statvfs(3). |
619 | 638 |
On Mac OS X f_bsize and f_frsize must be a power of 2 (minimum 512).""" |
620 | 639 |
return {} |
621 |
|
|
640 |
|
|
622 | 641 |
def symlink(self, target, source): |
623 | 642 |
raise FuseOSError(EROFS) |
624 |
|
|
643 |
|
|
625 | 644 |
def truncate(self, path, length, fh=None): |
626 | 645 |
raise FuseOSError(EROFS) |
627 |
|
|
646 |
|
|
628 | 647 |
def unlink(self, path): |
629 | 648 |
raise FuseOSError(EROFS) |
630 |
|
|
649 |
|
|
631 | 650 |
def utimens(self, path, times=None): |
632 | 651 |
"""Times is a (atime, mtime) tuple. If None use current time.""" |
633 | 652 |
return 0 |
634 |
|
|
653 |
|
|
635 | 654 |
def write(self, path, data, offset, fh): |
636 | 655 |
raise FuseOSError(EROFS) |
637 | 656 |
|
Also available in: Unified diff