summaryrefslogtreecommitdiff
path: root/fuse.py
diff options
context:
space:
mode:
authorTerence Honles <terence@honles.com>2012-04-23 19:28:44 -0700
committerTerence Honles <terence@honles.com>2012-04-23 19:28:44 -0700
commitfb8a3b11b7269d3f6d5c9e57d6784c503b0ce649 (patch)
tree1f8048cec87b14651aa43e5875091296084c30e0 /fuse.py
parent7457fb93236222c7786e5fb468a3ff1732abbaa9 (diff)
downloadfusepy-fb8a3b11b7269d3f6d5c9e57d6784c503b0ce649.tar.gz
organizing examples and package files
Diffstat (limited to 'fuse.py')
-rw-r--r--fuse.py692
1 files changed, 0 insertions, 692 deletions
diff --git a/fuse.py b/fuse.py
deleted file mode 100644
index e4e4c0e..0000000
--- a/fuse.py
+++ /dev/null
@@ -1,692 +0,0 @@
-# Copyright (c) 2008 Giorgos Verigakis <verigak@gmail.com>
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-from __future__ import division
-
-from ctypes import *
-from ctypes.util import find_library
-from errno import *
-from functools import partial
-from os import strerror
-from platform import machine, system
-from signal import signal, SIGINT, SIG_DFL
-from stat import S_IFDIR
-from traceback import print_exc
-
-
-__version__ = '1.1'
-
-_system = system()
-_machine = machine()
-
-if _system == 'Darwin':
- _libfuse_path = find_library('fuse4x') or find_library('osxfuse') or \
- find_library('fuse')
-else:
- _libfuse_path = find_library('fuse')
-if not _libfuse_path:
- raise EnvironmentError('Unable to find libfuse')
-
-if _system == 'Darwin':
- _libiconv = CDLL(find_library('iconv'), RTLD_GLOBAL) # libfuse dependency
-_libfuse = CDLL(_libfuse_path)
-
-if _system == 'Darwin' and hasattr(_libfuse, 'macfuse_version'):
- _system = 'Darwin-MacFuse'
-
-
-class c_timespec(Structure):
- _fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)]
-
-class c_utimbuf(Structure):
- _fields_ = [('actime', c_timespec), ('modtime', c_timespec)]
-
-class c_stat(Structure):
- pass # Platform dependent
-
-
-if _system in ('Darwin', 'Darwin-MacFuse', 'FreeBSD'):
- ENOTSUP = 45
- c_dev_t = c_int32
- c_fsblkcnt_t = c_ulong
- c_fsfilcnt_t = c_ulong
- c_gid_t = c_uint32
- c_mode_t = c_uint16
- c_off_t = c_int64
- c_pid_t = c_int32
- c_uid_t = c_uint32
- setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte),
- c_size_t, c_int, c_uint32)
- getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte),
- c_size_t, c_uint32)
- if _system == 'Darwin':
- c_stat._fields_ = [
- ('st_dev', c_dev_t),
- ('st_mode', c_mode_t),
- ('st_nlink', c_uint16),
- ('st_ino', c_uint64),
- ('st_uid', c_uid_t),
- ('st_gid', c_gid_t),
- ('st_rdev', c_dev_t),
- ('st_atimespec', c_timespec),
- ('st_mtimespec', c_timespec),
- ('st_ctimespec', c_timespec),
- ('st_birthtimespec', c_timespec),
- ('st_size', c_off_t),
- ('st_blocks', c_int64),
- ('st_blksize', c_int32),
- ('st_flags', c_int32),
- ('st_gen', c_int32),
- ('st_lspare', c_int32),
- ('st_qspare', c_int64)]
- else:
- c_stat._fields_ = [
- ('st_dev', c_dev_t),
- ('st_ino', c_uint32),
- ('st_mode', c_mode_t),
- ('st_nlink', c_uint16),
- ('st_uid', c_uid_t),
- ('st_gid', c_gid_t),
- ('st_rdev', c_dev_t),
- ('st_atimespec', c_timespec),
- ('st_mtimespec', c_timespec),
- ('st_ctimespec', c_timespec),
- ('st_size', c_off_t),
- ('st_blocks', c_int64),
- ('st_blksize', c_int32)]
-elif _system == 'Linux':
- ENOTSUP = 95
- c_dev_t = c_ulonglong
- c_fsblkcnt_t = c_ulonglong
- c_fsfilcnt_t = c_ulonglong
- c_gid_t = c_uint
- c_mode_t = c_uint
- c_off_t = c_longlong
- c_pid_t = c_int
- c_uid_t = c_uint
- setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int)
- getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t)
-
- if _machine == 'x86_64':
- c_stat._fields_ = [
- ('st_dev', c_dev_t),
- ('st_ino', c_ulong),
- ('st_nlink', c_ulong),
- ('st_mode', c_mode_t),
- ('st_uid', c_uid_t),
- ('st_gid', c_gid_t),
- ('__pad0', c_int),
- ('st_rdev', c_dev_t),
- ('st_size', c_off_t),
- ('st_blksize', c_long),
- ('st_blocks', c_long),
- ('st_atimespec', c_timespec),
- ('st_mtimespec', c_timespec),
- ('st_ctimespec', c_timespec)]
- elif _machine == 'ppc':
- c_stat._fields_ = [
- ('st_dev', c_dev_t),
- ('st_ino', c_ulonglong),
- ('st_mode', c_mode_t),
- ('st_nlink', c_uint),
- ('st_uid', c_uid_t),
- ('st_gid', c_gid_t),
- ('st_rdev', c_dev_t),
- ('__pad2', c_ushort),
- ('st_size', c_off_t),
- ('st_blksize', c_long),
- ('st_blocks', c_longlong),
- ('st_atimespec', c_timespec),
- ('st_mtimespec', c_timespec),
- ('st_ctimespec', c_timespec)]
- else:
- # i686, use as fallback for everything else
- c_stat._fields_ = [
- ('st_dev', c_dev_t),
- ('__pad1', c_ushort),
- ('__st_ino', c_ulong),
- ('st_mode', c_mode_t),
- ('st_nlink', c_uint),
- ('st_uid', c_uid_t),
- ('st_gid', c_gid_t),
- ('st_rdev', c_dev_t),
- ('__pad2', c_ushort),
- ('st_size', c_off_t),
- ('st_blksize', c_long),
- ('st_blocks', c_longlong),
- ('st_atimespec', c_timespec),
- ('st_mtimespec', c_timespec),
- ('st_ctimespec', c_timespec),
- ('st_ino', c_ulonglong)]
-else:
- raise NotImplementedError('%s is not supported.' % _system)
-
-
-class c_statvfs(Structure):
- _fields_ = [
- ('f_bsize', c_ulong),
- ('f_frsize', c_ulong),
- ('f_blocks', c_fsblkcnt_t),
- ('f_bfree', c_fsblkcnt_t),
- ('f_bavail', c_fsblkcnt_t),
- ('f_files', c_fsfilcnt_t),
- ('f_ffree', c_fsfilcnt_t),
- ('f_favail', c_fsfilcnt_t)]
-
-if _system == 'FreeBSD':
- c_fsblkcnt_t = c_uint64
- c_fsfilcnt_t = c_uint64
- setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int)
- getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t)
- class c_statvfs(Structure):
- _fields_ = [
- ('f_bavail', c_fsblkcnt_t),
- ('f_bfree', c_fsblkcnt_t),
- ('f_blocks', c_fsblkcnt_t),
- ('f_favail', c_fsfilcnt_t),
- ('f_ffree', c_fsfilcnt_t),
- ('f_files', c_fsfilcnt_t),
- ('f_bsize', c_ulong),
- ('f_flag', c_ulong),
- ('f_frsize', c_ulong)]
-
-class fuse_file_info(Structure):
- _fields_ = [
- ('flags', c_int),
- ('fh_old', c_ulong),
- ('writepage', c_int),
- ('direct_io', c_uint, 1),
- ('keep_cache', c_uint, 1),
- ('flush', c_uint, 1),
- ('padding', c_uint, 29),
- ('fh', c_uint64),
- ('lock_owner', c_uint64)]
-
-class fuse_context(Structure):
- _fields_ = [
- ('fuse', c_voidp),
- ('uid', c_uid_t),
- ('gid', c_gid_t),
- ('pid', c_pid_t),
- ('private_data', c_voidp)]
-
-_libfuse.fuse_get_context.restype = POINTER(fuse_context)
-
-class fuse_operations(Structure):
- _fields_ = [
- ('getattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat))),
- ('readlink', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t)),
- ('getdir', c_voidp), # Deprecated, use readdir
- ('mknod', CFUNCTYPE(c_int, c_char_p, c_mode_t, c_dev_t)),
- ('mkdir', CFUNCTYPE(c_int, c_char_p, c_mode_t)),
- ('unlink', CFUNCTYPE(c_int, c_char_p)),
- ('rmdir', CFUNCTYPE(c_int, c_char_p)),
- ('symlink', CFUNCTYPE(c_int, c_char_p, c_char_p)),
- ('rename', CFUNCTYPE(c_int, c_char_p, c_char_p)),
- ('link', CFUNCTYPE(c_int, c_char_p, c_char_p)),
- ('chmod', CFUNCTYPE(c_int, c_char_p, c_mode_t)),
- ('chown', CFUNCTYPE(c_int, c_char_p, c_uid_t, c_gid_t)),
- ('truncate', CFUNCTYPE(c_int, c_char_p, c_off_t)),
- ('utime', c_voidp), # Deprecated, use utimens
- ('open', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
- ('read', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t,
- POINTER(fuse_file_info))),
- ('write', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t,
- POINTER(fuse_file_info))),
- ('statfs', CFUNCTYPE(c_int, c_char_p, POINTER(c_statvfs))),
- ('flush', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
- ('release', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
- ('fsync', CFUNCTYPE(c_int, c_char_p, c_int, POINTER(fuse_file_info))),
- ('setxattr', setxattr_t),
- ('getxattr', getxattr_t),
- ('listxattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t)),
- ('removexattr', CFUNCTYPE(c_int, c_char_p, c_char_p)),
- ('opendir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
- ('readdir', CFUNCTYPE(c_int, c_char_p, c_voidp, CFUNCTYPE(c_int, c_voidp,
- c_char_p, POINTER(c_stat), c_off_t), c_off_t, POINTER(fuse_file_info))),
- ('releasedir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
- ('fsyncdir', CFUNCTYPE(c_int, c_char_p, c_int, POINTER(fuse_file_info))),
- ('init', CFUNCTYPE(c_voidp, c_voidp)),
- ('destroy', CFUNCTYPE(c_voidp, c_voidp)),
- ('access', CFUNCTYPE(c_int, c_char_p, c_int)),
- ('create', CFUNCTYPE(c_int, c_char_p, c_mode_t, POINTER(fuse_file_info))),
- ('ftruncate', CFUNCTYPE(c_int, c_char_p, c_off_t, POINTER(fuse_file_info))),
- ('fgetattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat),
- POINTER(fuse_file_info))),
- ('lock', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info), c_int, c_voidp)),
- ('utimens', CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))),
- ('bmap', CFUNCTYPE(c_int, c_char_p, c_size_t, POINTER(c_ulonglong)))]
-
-
-def time_of_timespec(ts):
- return ts.tv_sec + ts.tv_nsec / 10 ** 9
-
-def set_st_attrs(st, attrs):
- for key, val in attrs.items():
- if key in ('st_atime', 'st_mtime', 'st_ctime'):
- timespec = getattr(st, key + 'spec')
- timespec.tv_sec = int(val)
- timespec.tv_nsec = int((val - timespec.tv_sec) * 10 ** 9)
- elif hasattr(st, key):
- setattr(st, key, val)
-
-
-def fuse_get_context():
- """Returns a (uid, gid, pid) tuple"""
- ctxp = _libfuse.fuse_get_context()
- ctx = ctxp.contents
- return ctx.uid, ctx.gid, ctx.pid
-
-
-class FuseOSError(OSError):
- def __init__(self, errno):
- super(FuseOSError, self).__init__(errno, strerror(errno))
-
-
-class FUSE(object):
- """This class is the lower level interface and should not be subclassed
- under normal use. Its methods are called by fuse.
- Assumes API version 2.6 or later."""
-
- def __init__(self, operations, mountpoint, raw_fi=False, **kwargs):
- """Setting raw_fi to True will cause FUSE to pass the fuse_file_info
- class as is to Operations, instead of just the fh field.
- This gives you access to direct_io, keep_cache, etc."""
-
- self.operations = operations
- self.raw_fi = raw_fi
- args = ['fuse']
- if kwargs.pop('foreground', False):
- args.append('-f')
- if kwargs.pop('debug', False):
- args.append('-d')
- if kwargs.pop('nothreads', False):
- args.append('-s')
- kwargs.setdefault('fsname', operations.__class__.__name__)
- args.append('-o')
- args.append(','.join(key if val == True else '%s=%s' % (key, val)
- for key, val in kwargs.items()))
- args.append(mountpoint)
- argv = (c_char_p * len(args))(*args)
-
- fuse_ops = fuse_operations()
- for name, prototype in fuse_operations._fields_:
- if prototype != c_voidp and getattr(operations, name, None):
- op = partial(self._wrapper_, getattr(self, name))
- setattr(fuse_ops, name, prototype(op))
-
- old_handler = signal(SIGINT, SIG_DFL)
-
- err = _libfuse.fuse_main_real(len(args), argv, pointer(fuse_ops),
- sizeof(fuse_ops), None)
-
- signal(SIGINT, old_handler)
-
- del self.operations # Invoke the destructor
- if err:
- raise RuntimeError(err)
-
- def _wrapper_(self, func, *args, **kwargs):
- """Decorator for the methods that follow"""
- try:
- return func(*args, **kwargs) or 0
- except OSError, e:
- return -(e.errno or EFAULT)
- except:
- print_exc()
- return -EFAULT
-
- def getattr(self, path, buf):
- return self.fgetattr(path, buf, None)
-
- def readlink(self, path, buf, bufsize):
- ret = self.operations('readlink', path)
- data = create_string_buffer(ret[:bufsize - 1])
- memmove(buf, data, len(data))
- return 0
-
- def mknod(self, path, mode, dev):
- return self.operations('mknod', path, mode, dev)
-
- def mkdir(self, path, mode):
- return self.operations('mkdir', path, mode)
-
- def unlink(self, path):
- return self.operations('unlink', path)
-
- def rmdir(self, path):
- return self.operations('rmdir', path)
-
- def symlink(self, source, target):
- return self.operations('symlink', target, source)
-
- def rename(self, old, new):
- return self.operations('rename', old, new)
-
- def link(self, source, target):
- return self.operations('link', target, source)
-
- def chmod(self, path, mode):
- return self.operations('chmod', path, mode)
-
- def chown(self, path, uid, gid):
- # Check if any of the arguments is a -1 that has overflowed
- if c_uid_t(uid + 1).value == 0:
- uid = -1
- if c_gid_t(gid + 1).value == 0:
- gid = -1
- return self.operations('chown', path, uid, gid)
-
- def truncate(self, path, length):
- return self.operations('truncate', path, length)
-
- def open(self, path, fip):
- fi = fip.contents
- if self.raw_fi:
- return self.operations('open', path, fi)
- else:
- fi.fh = self.operations('open', path, fi.flags)
- return 0
-
- def read(self, path, buf, size, offset, fip):
- fh = fip.contents if self.raw_fi else fip.contents.fh
- ret = self.operations('read', path, size, offset, fh)
- if not ret:
- return 0
- data = create_string_buffer(ret[:size], size)
- memmove(buf, data, size)
- return size
-
- def write(self, path, buf, size, offset, fip):
- data = string_at(buf, size)
- fh = fip.contents if self.raw_fi else fip.contents.fh
- return self.operations('write', path, data, offset, fh)
-
- def statfs(self, path, buf):
- stv = buf.contents
- attrs = self.operations('statfs', path)
- for key, val in attrs.items():
- if hasattr(stv, key):
- setattr(stv, key, val)
- return 0
-
- def flush(self, path, fip):
- fh = fip.contents if self.raw_fi else fip.contents.fh
- return self.operations('flush', path, fh)
-
- def release(self, path, fip):
- fh = fip.contents if self.raw_fi else fip.contents.fh
- return self.operations('release', path, fh)
-
- def fsync(self, path, datasync, fip):
- fh = fip.contents if self.raw_fi else fip.contents.fh
- return self.operations('fsync', path, datasync, fh)
-
- def setxattr(self, path, name, value, size, options, *args):
- data = string_at(value, size)
- return self.operations('setxattr', path, name, data, options, *args)
-
- def getxattr(self, path, name, value, size, *args):
- ret = self.operations('getxattr', path, name, *args)
- retsize = len(ret)
- buf = create_string_buffer(ret, retsize) # Does not add trailing 0
- if bool(value):
- if retsize > size:
- return -ERANGE
- memmove(value, buf, retsize)
- return retsize
-
- def listxattr(self, path, namebuf, size):
- ret = self.operations('listxattr', path)
- buf = create_string_buffer('\x00'.join(ret)) if ret else ''
- bufsize = len(buf)
- if bool(namebuf):
- if bufsize > size:
- return -ERANGE
- memmove(namebuf, buf, bufsize)
- return bufsize
-
- def removexattr(self, path, name):
- return self.operations('removexattr', path, name)
-
- def opendir(self, path, fip):
- # Ignore raw_fi
- fip.contents.fh = self.operations('opendir', path)
- return 0
-
- def readdir(self, path, buf, filler, offset, fip):
- # Ignore raw_fi
- for item in self.operations('readdir', path, fip.contents.fh):
- if isinstance(item, str):
- name, st, offset = item, None, 0
- else:
- name, attrs, offset = item
- if attrs:
- st = c_stat()
- set_st_attrs(st, attrs)
- else:
- st = None
- if filler(buf, name, st, offset) != 0:
- break
- return 0
-
- def releasedir(self, path, fip):
- # Ignore raw_fi
- return self.operations('releasedir', path, fip.contents.fh)
-
- def fsyncdir(self, path, datasync, fip):
- # Ignore raw_fi
- return self.operations('fsyncdir', path, datasync, fip.contents.fh)
-
- def init(self, conn):
- return self.operations('init', '/')
-
- def destroy(self, private_data):
- return self.operations('destroy', '/')
-
- def access(self, path, amode):
- return self.operations('access', path, amode)
-
- def create(self, path, mode, fip):
- fi = fip.contents
- if self.raw_fi:
- return self.operations('create', path, mode, fi)
- else:
- fi.fh = self.operations('create', path, mode)
- return 0
-
- def ftruncate(self, path, length, fip):
- fh = fip.contents if self.raw_fi else fip.contents.fh
- return self.operations('truncate', path, length, fh)
-
- def fgetattr(self, path, buf, fip):
- memset(buf, 0, sizeof(c_stat))
- st = buf.contents
- fh = fip and (fip.contents if self.raw_fi else fip.contents.fh)
- attrs = self.operations('getattr', path, fh)
- set_st_attrs(st, attrs)
- return 0
-
- def lock(self, path, fip, cmd, lock):
- fh = fip.contents if self.raw_fi else fip.contents.fh
- return self.operations('lock', path, fh, cmd, lock)
-
- def utimens(self, path, buf):
- if buf:
- atime = time_of_timespec(buf.contents.actime)
- mtime = time_of_timespec(buf.contents.modtime)
- times = (atime, mtime)
- else:
- times = None
- return self.operations('utimens', path, times)
-
- def bmap(self, path, blocksize, idx):
- return self.operations('bmap', path, blocksize, idx)
-
-
-class Operations(object):
- """This class should be subclassed and passed as an argument to FUSE on
- initialization. All operations should raise a FuseOSError exception
- on error.
-
- When in doubt of what an operation should do, check the FUSE header
- file or the corresponding system call man page."""
-
- def __call__(self, op, *args):
- if not hasattr(self, op):
- raise FuseOSError(EFAULT)
- return getattr(self, op)(*args)
-
- def access(self, path, amode):
- return 0
-
- bmap = None
-
- def chmod(self, path, mode):
- raise FuseOSError(EROFS)
-
- def chown(self, path, uid, gid):
- raise FuseOSError(EROFS)
-
- def create(self, path, mode, fi=None):
- """When raw_fi is False (default case), fi is None and create should
- return a numerical file handle.
- When raw_fi is True the file handle should be set directly by create
- and return 0."""
- raise FuseOSError(EROFS)
-
- def destroy(self, path):
- """Called on filesystem destruction. Path is always /"""
- pass
-
- def flush(self, path, fh):
- return 0
-
- def fsync(self, path, datasync, fh):
- return 0
-
- def fsyncdir(self, path, datasync, fh):
- return 0
-
- def getattr(self, path, fh=None):
- """Returns a dictionary with keys identical to the stat C structure
- of stat(2).
- st_atime, st_mtime and st_ctime should be floats.
- NOTE: There is an incombatibility between Linux and Mac OS X concerning
- st_nlink of directories. Mac OS X counts all files inside the directory,
- while Linux counts only the subdirectories."""
-
- if path != '/':
- raise FuseOSError(ENOENT)
- return dict(st_mode=(S_IFDIR | 0755), st_nlink=2)
-
- def getxattr(self, path, name, position=0):
- raise FuseOSError(ENOTSUP)
-
- def init(self, path):
- """Called on filesystem initialization. Path is always /
- Use it instead of __init__ if you start threads on initialization."""
- pass
-
- def link(self, target, source):
- raise FuseOSError(EROFS)
-
- def listxattr(self, path):
- return []
-
- lock = None
-
- def mkdir(self, path, mode):
- raise FuseOSError(EROFS)
-
- def mknod(self, path, mode, dev):
- raise FuseOSError(EROFS)
-
- def open(self, path, flags):
- """When raw_fi is False (default case), open should return a numerical
- file handle.
- When raw_fi is True the signature of open becomes:
- open(self, path, fi)
- and the file handle should be set directly."""
- return 0
-
- def opendir(self, path):
- """Returns a numerical file handle."""
- return 0
-
- def read(self, path, size, offset, fh):
- """Returns a string containing the data requested."""
- raise FuseOSError(EIO)
-
- def readdir(self, path, fh):
- """Can return either a list of names, or a list of (name, attrs, offset)
- tuples. attrs is a dict as in getattr."""
- return ['.', '..']
-
- def readlink(self, path):
- raise FuseOSError(ENOENT)
-
- def release(self, path, fh):
- return 0
-
- def releasedir(self, path, fh):
- return 0
-
- def removexattr(self, path, name):
- raise FuseOSError(ENOTSUP)
-
- def rename(self, old, new):
- raise FuseOSError(EROFS)
-
- def rmdir(self, path):
- raise FuseOSError(EROFS)
-
- def setxattr(self, path, name, value, options, position=0):
- raise FuseOSError(ENOTSUP)
-
- def statfs(self, path):
- """Returns a dictionary with keys identical to the statvfs C structure
- of statvfs(3).
- On Mac OS X f_bsize and f_frsize must be a power of 2 (minimum 512)."""
- return {}
-
- def symlink(self, target, source):
- raise FuseOSError(EROFS)
-
- def truncate(self, path, length, fh=None):
- raise FuseOSError(EROFS)
-
- def unlink(self, path):
- raise FuseOSError(EROFS)
-
- def utimens(self, path, times=None):
- """Times is a (atime, mtime) tuple. If None use current time."""
- return 0
-
- def write(self, path, data, offset, fh):
- raise FuseOSError(EROFS)
-
-
-class LoggingMixIn:
- def __call__(self, op, path, *args):
- print '->', op, path, repr(args)
- ret = '[Unhandled Exception]'
- try:
- ret = getattr(self, op)(path, *args)
- return ret
- except OSError, e:
- ret = str(e)
- raise
- finally:
- print '<-', op, repr(ret)