55import logging
66import os
77import threading
8- from os .path import realpath
98
109import mfusepy as fuse
1110
1211
13- class Loopback (fuse .LoggingMixIn , fuse .Operations ):
12+ def with_root_path (func ):
13+ def wrapper (self , path , * args , ** kwargs ):
14+ return func (self , self .root + path , * args , ** kwargs )
15+
16+ return wrapper
17+
18+
19+ def static_with_root_path (func ):
20+ def wrapper (self , path , * args , ** kwargs ):
21+ return func (self .root + path , * args , ** kwargs )
22+
23+ return wrapper
24+
25+
26+ class Loopback (fuse .Operations ):
1427 def __init__ (self , root ):
15- self .root = realpath (root )
28+ self .root = os . path . realpath (root )
1629 self .rwlock = threading .Lock ()
1730
18- def __call__ (self , op , path , * args ):
19- return super ().__call__ (op , self .root + path , * args )
20-
31+ @with_root_path
2132 def access (self , path , amode ):
2233 if not os .access (path , amode ):
2334 raise fuse .FuseOSError (errno .EACCES )
2435
25- chmod = os .chmod
26- chown = os .chown
36+ chmod = static_with_root_path ( os .chmod )
37+ chown = static_with_root_path ( os .chown )
2738
39+ @with_root_path
2840 def create (self , path , mode , fi = None ):
2941 return os .open (path , os .O_WRONLY | os .O_CREAT | os .O_TRUNC , mode )
3042
43+ @with_root_path
3144 def flush (self , path , fh ):
3245 return os .fsync (fh )
3346
47+ @with_root_path
3448 def fsync (self , path , datasync , fh ):
3549 if datasync != 0 :
3650 return os .fdatasync (fh )
3751 return os .fsync (fh )
3852
53+ @fuse .log_callback
54+ @with_root_path
3955 def getattr (self , path , fh = None ):
4056 st = os .lstat (path )
4157 return {
4258 key : getattr (st , key )
4359 for key in ('st_atime' , 'st_ctime' , 'st_gid' , 'st_mode' , 'st_mtime' , 'st_nlink' , 'st_size' , 'st_uid' )
4460 }
4561
62+ @with_root_path
4663 def link (self , target , source ):
4764 return os .link (self .root + source , target )
4865
49- mkdir = os .mkdir
50- mknod = os .mknod
51- open = os .open
66+ mkdir = static_with_root_path ( os .mkdir )
67+ mknod = static_with_root_path ( os .mknod )
68+ open = static_with_root_path ( os .open )
5269
70+ @with_root_path
5371 def read (self , path , size , offset , fh ):
5472 with self .rwlock :
5573 os .lseek (fh , offset , 0 )
5674 return os .read (fh , size )
5775
76+ @with_root_path
5877 def readdir (self , path , fh ):
5978 return ['.' , '..' , * os .listdir (path )]
6079
61- readlink = os .readlink
80+ readlink = static_with_root_path ( os .readlink )
6281
82+ @with_root_path
6383 def release (self , path , fh ):
6484 return os .close (fh )
6585
86+ @with_root_path
6687 def rename (self , old , new ):
6788 return os .rename (old , self .root + new )
6889
69- rmdir = os .rmdir
90+ rmdir = static_with_root_path ( os .rmdir )
7091
92+ @with_root_path
7193 def statfs (self , path ):
7294 stv = os .statvfs (path )
7395 return {
@@ -86,16 +108,20 @@ def statfs(self, path):
86108 )
87109 }
88110
111+ @with_root_path
89112 def symlink (self , target , source ):
90113 return os .symlink (source , target )
91114
115+ @with_root_path
92116 def truncate (self , path , length , fh = None ):
93117 with open (path , 'r+' ) as f :
94118 f .truncate (length )
95119
96- unlink = os .unlink
97- utimens = os .utime
120+ unlink = static_with_root_path ( os .unlink )
121+ utimens = static_with_root_path ( os .utime )
98122
123+ @fuse .log_callback
124+ @with_root_path
99125 def write (self , path , data , offset , fh ):
100126 with self .rwlock :
101127 os .lseek (fh , offset , 0 )
0 commit comments