summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTerence Honles <terence@honles.com>2016-04-04 16:22:00 -0700
committerTerence Honles <terence@honles.com>2016-04-04 16:22:00 -0700
commit9636e51877b5fac05d74cd1a45c29df2079c8470 (patch)
tree6e71e6fb23b3ca708c57f2091f412d4623f132a9
parent4237e01d96bf7beb45c4046a022c64f0c86ff66d (diff)
parente1dd73ac2f11bcbc6717ae3fc0e8e501ce12f081 (diff)
downloadfusepy-9636e51877b5fac05d74cd1a45c29df2079c8470.tar.gz
Merge pull request #48 from rianhunter/master
Allow fuse flags, missing time fields, and optional paths
-rw-r--r--fuse.py56
1 files changed, 40 insertions, 16 deletions
diff --git a/fuse.py b/fuse.py
index c0978ea..0500af8 100644
--- a/fuse.py
+++ b/fuse.py
@@ -370,6 +370,10 @@ class fuse_operations(Structure):
('utimens', CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))),
('bmap', CFUNCTYPE(c_int, c_char_p, c_size_t, POINTER(c_ulonglong))),
+ ('flag_nullpath_ok', c_uint, 1),
+ ('flag_nopath', c_uint, 1),
+ ('flag_utime_omit_ok', c_uint, 1),
+ ('flag_reserved', c_uint, 29),
]
@@ -379,7 +383,9 @@ def time_of_timespec(ts):
def set_st_attrs(st, attrs):
for key, val in attrs.items():
if key in ('st_atime', 'st_mtime', 'st_ctime', 'st_birthtime'):
- timespec = getattr(st, key + 'spec')
+ timespec = getattr(st, key + 'spec', None)
+ if timespec is None:
+ continue
timespec.tv_sec = int(val)
timespec.tv_nsec = int((val - timespec.tv_sec) * 10 ** 9)
elif hasattr(st, key):
@@ -441,10 +447,20 @@ class FUSE(object):
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))
+ for ent in fuse_operations._fields_:
+ name, prototype = ent[:2]
+
+ val = getattr(operations, name, None)
+ if val is None:
+ continue
+
+ # Function pointer members are tested for using the
+ # getattr(operations, name) above but are dynamically
+ # invoked using self.operations(name)
+ if hasattr(prototype, 'argtypes'):
+ val = prototype(partial(self._wrapper, getattr(self, name)))
+
+ setattr(fuse_ops, name, val)
try:
old_handler = signal(SIGINT, SIG_DFL)
@@ -483,6 +499,14 @@ class FUSE(object):
print_exc()
return -EFAULT
+ def _decode_optional_path(self, path):
+ # NB: this method is intended for fuse operations that
+ # allow the path argument to be NULL,
+ # *not* as a generic path decoding method
+ if path is None:
+ return None
+ return path.decode(self.encoding)
+
def getattr(self, path, buf):
return self.fgetattr(path, buf, None)
@@ -555,7 +579,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- ret = self.operations('read', path.decode(self.encoding), size,
+ ret = self.operations('read', self._decode_optional_path(path), size,
offset, fh)
if not ret: return 0
@@ -576,7 +600,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- return self.operations('write', path.decode(self.encoding), data,
+ return self.operations('write', self._decode_optional_path(path), data,
offset, fh)
def statfs(self, path, buf):
@@ -594,7 +618,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- return self.operations('flush', path.decode(self.encoding), fh)
+ return self.operations('flush', self._decode_optional_path(path), fh)
def release(self, path, fip):
if self.raw_fi:
@@ -602,7 +626,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- return self.operations('release', path.decode(self.encoding), fh)
+ return self.operations('release', self._decode_optional_path(path), fh)
def fsync(self, path, datasync, fip):
if self.raw_fi:
@@ -610,7 +634,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- return self.operations('fsync', path.decode(self.encoding), datasync,
+ return self.operations('fsync', self._decode_optional_path(path), datasync,
fh)
def setxattr(self, path, name, value, size, options, *args):
@@ -665,7 +689,7 @@ class FUSE(object):
def readdir(self, path, buf, filler, offset, fip):
# Ignore raw_fi
- for item in self.operations('readdir', path.decode(self.encoding),
+ for item in self.operations('readdir', self._decode_optional_path(path),
fip.contents.fh):
if isinstance(item, basestring):
@@ -685,12 +709,12 @@ class FUSE(object):
def releasedir(self, path, fip):
# Ignore raw_fi
- return self.operations('releasedir', path.decode(self.encoding),
+ return self.operations('releasedir', self._decode_optional_path(path),
fip.contents.fh)
def fsyncdir(self, path, datasync, fip):
# Ignore raw_fi
- return self.operations('fsyncdir', path.decode(self.encoding),
+ return self.operations('fsyncdir', self._decode_optional_path(path),
datasync, fip.contents.fh)
def init(self, conn):
@@ -718,7 +742,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- return self.operations('truncate', path.decode(self.encoding),
+ return self.operations('truncate', self._decode_optional_path(path),
length, fh)
def fgetattr(self, path, buf, fip):
@@ -732,7 +756,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- attrs = self.operations('getattr', path.decode(self.encoding), fh)
+ attrs = self.operations('getattr', self._decode_optional_path(path), fh)
set_st_attrs(st, attrs)
return 0
@@ -742,7 +766,7 @@ class FUSE(object):
else:
fh = fip.contents.fh
- return self.operations('lock', path.decode(self.encoding), fh, cmd,
+ return self.operations('lock', self._decode_optional_path(path), fh, cmd,
lock)
def utimens(self, path, buf):