tahoe-lafs/contrib/fuse/impl_b/pyfuse/test.py

173 lines
4.8 KiB
Python

from handler import Handler
import stat, errno, os, time
from cStringIO import StringIO
from kernel import *
UID = os.getuid()
GID = os.getgid()
UMASK = os.umask(0); os.umask(UMASK)
INFINITE = 86400.0
class Node(object):
__slots__ = ['attr', 'data']
def __init__(self, attr, data=None):
self.attr = attr
self.data = data
def type(self):
return mode2type(self.attr.mode)
def modified(self):
self.attr.mtime = self.attr.atime = time.time()
t = self.type()
if t == TYPE_REG:
f = self.data
pos = f.tell()
f.seek(0, 2)
self.attr.size = f.tell()
f.seek(pos)
elif t == TYPE_DIR:
nsubdirs = 0
for nodeid in self.data.values():
nsubdirs += nodeid & 1
self.attr.nlink = 2 + nsubdirs
def newattr(s, mode=0666):
now = time.time()
return fuse_attr(ino = INVALID_INO,
size = 0,
mode = s | (mode & ~UMASK),
nlink = 1 + (s == stat.S_IFDIR),
atime = now,
mtime = now,
ctime = now,
uid = UID,
gid = GID)
# ____________________________________________________________
class Filesystem:
def __init__(self, rootnode):
self.nodes = {FUSE_ROOT_ID: rootnode}
self.nextid = 2
assert self.nextid > FUSE_ROOT_ID
def getnode(self, nodeid):
try:
return self.nodes[nodeid]
except KeyError:
raise IOError(errno.ESTALE, nodeid)
def forget(self, nodeid):
pass
def cachenode(self, node):
id = self.nextid
self.nextid += 2
if node.type() == TYPE_DIR:
id += 1
self.nodes[id] = node
return id
def getattr(self, node):
return node.attr, INFINITE
def setattr(self, node, mode=None, uid=None, gid=None,
size=None, atime=None, mtime=None):
if mode is not None: node.attr.mode = (node.attr.mode&~0777) | mode
if uid is not None: node.attr.uid = uid
if gid is not None: node.attr.gid = gid
if atime is not None: node.attr.atime = atime
if mtime is not None: node.attr.mtime = mtime
if size is not None and node.type() == TYPE_REG:
node.data.seek(size)
node.data.truncate()
def listdir(self, node):
for name, subnodeid in node.data.items():
subnode = self.nodes[subnodeid]
yield name, subnode.type()
def lookup(self, node, name):
try:
return node.data[name], INFINITE
except KeyError:
pass
if hasattr(node, 'findnode'):
try:
subnode = node.findnode(name)
except KeyError:
pass
else:
id = self.cachenode(subnode)
node.data[name] = id
return id, INFINITE
raise IOError(errno.ENOENT, name)
def open(self, node, mode):
return node.data
def mknod(self, node, name, mode):
subnode = Node(newattr(mode & 0170000, mode & 0777))
if subnode.type() == TYPE_REG:
subnode.data = StringIO()
else:
raise NotImplementedError
id = self.cachenode(subnode)
node.data[name] = id
node.modified()
return id, INFINITE
def mkdir(self, node, name, mode):
subnode = Node(newattr(stat.S_IFDIR, mode & 0777), {})
id = self.cachenode(subnode)
node.data[name] = id
node.modified()
return id, INFINITE
def symlink(self, node, linkname, target):
subnode = Node(newattr(stat.S_IFLNK, 0777), target)
id = self.cachenode(subnode)
node.data[linkname] = id
node.modified()
return id, INFINITE
def readlink(self, node):
assert node.type() == TYPE_LNK
return node.data
def unlink(self, node, name):
try:
del node.data[name]
except KeyError:
raise IOError(errno.ENOENT, name)
node.modified()
rmdir = unlink
def rename(self, oldnode, oldname, newnode, newname):
if newnode.type() != TYPE_DIR:
raise IOError(errno.ENOTDIR, newnode)
try:
nodeid = oldnode.data.pop(oldname)
except KeyError:
raise IOError(errno.ENOENT, oldname)
oldnode.modified()
newnode.data[newname] = nodeid
newnode.modified()
def modified(self, node):
node.modified()
# ____________________________________________________________
if __name__ == '__main__':
root = Node(newattr(stat.S_IFDIR), {})
handler = Handler('/home/arigo/mnt', Filesystem(root))
handler.loop_forever()