root / pithos / lib / fuse.py @ 6749c3bd
History | View | Annotate | Download (22.3 kB)
1 | 49350be7 | Giorgos Verigakis | # Copyright (c) 2008 Giorgos Verigakis <verigak@gmail.com>
|
---|---|---|---|
2 | 49350be7 | Giorgos Verigakis | #
|
3 | 49350be7 | Giorgos Verigakis | # Permission to use, copy, modify, and distribute this software for any
|
4 | 49350be7 | Giorgos Verigakis | # purpose with or without fee is hereby granted, provided that the above
|
5 | 49350be7 | Giorgos Verigakis | # copyright notice and this permission notice appear in all copies.
|
6 | 49350be7 | Giorgos Verigakis | #
|
7 | 49350be7 | Giorgos Verigakis | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8 | 49350be7 | Giorgos Verigakis | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9 | 49350be7 | Giorgos Verigakis | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10 | 49350be7 | Giorgos Verigakis | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11 | 49350be7 | Giorgos Verigakis | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12 | 49350be7 | Giorgos Verigakis | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
13 | 49350be7 | Giorgos Verigakis | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14 | 49350be7 | Giorgos Verigakis | |
15 | 49350be7 | Giorgos Verigakis | from __future__ import division |
16 | 49350be7 | Giorgos Verigakis | |
17 | 49350be7 | Giorgos Verigakis | from ctypes import * |
18 | 49350be7 | Giorgos Verigakis | from ctypes.util import find_library |
19 | 49350be7 | Giorgos Verigakis | from errno import * |
20 | 49350be7 | Giorgos Verigakis | from functools import partial |
21 | 49350be7 | Giorgos Verigakis | from os import strerror |
22 | 49350be7 | Giorgos Verigakis | from platform import machine, system |
23 | 49350be7 | Giorgos Verigakis | from stat import S_IFDIR |
24 | 49350be7 | Giorgos Verigakis | from traceback import print_exc |
25 | 49350be7 | Giorgos Verigakis | |
26 | 49350be7 | Giorgos Verigakis | |
27 | 49350be7 | Giorgos Verigakis | class c_timespec(Structure): |
28 | 49350be7 | Giorgos Verigakis | _fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)] |
29 | 49350be7 | Giorgos Verigakis | |
30 | 49350be7 | Giorgos Verigakis | class c_utimbuf(Structure): |
31 | 49350be7 | Giorgos Verigakis | _fields_ = [('actime', c_timespec), ('modtime', c_timespec)] |
32 | 49350be7 | Giorgos Verigakis | |
33 | 49350be7 | Giorgos Verigakis | class c_stat(Structure): |
34 | 49350be7 | Giorgos Verigakis | pass # Platform dependent |
35 | 49350be7 | Giorgos Verigakis | |
36 | 49350be7 | Giorgos Verigakis | _system = system() |
37 | 49350be7 | Giorgos Verigakis | if _system in ('Darwin', 'FreeBSD'): |
38 | 49350be7 | Giorgos Verigakis | _libiconv = CDLL(find_library("iconv"), RTLD_GLOBAL) # libfuse dependency |
39 | 49350be7 | Giorgos Verigakis | ENOTSUP = 45
|
40 | 49350be7 | Giorgos Verigakis | c_dev_t = c_int32 |
41 | 49350be7 | Giorgos Verigakis | c_fsblkcnt_t = c_ulong |
42 | 49350be7 | Giorgos Verigakis | c_fsfilcnt_t = c_ulong |
43 | 49350be7 | Giorgos Verigakis | c_gid_t = c_uint32 |
44 | 49350be7 | Giorgos Verigakis | c_mode_t = c_uint16 |
45 | 49350be7 | Giorgos Verigakis | c_off_t = c_int64 |
46 | 49350be7 | Giorgos Verigakis | c_pid_t = c_int32 |
47 | 49350be7 | Giorgos Verigakis | c_uid_t = c_uint32 |
48 | 49350be7 | Giorgos Verigakis | setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), |
49 | 49350be7 | Giorgos Verigakis | c_size_t, c_int, c_uint32) |
50 | 49350be7 | Giorgos Verigakis | getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), |
51 | 49350be7 | Giorgos Verigakis | c_size_t, c_uint32) |
52 | 49350be7 | Giorgos Verigakis | c_stat._fields_ = [ |
53 | 49350be7 | Giorgos Verigakis | ('st_dev', c_dev_t),
|
54 | 49350be7 | Giorgos Verigakis | ('st_ino', c_uint32),
|
55 | 49350be7 | Giorgos Verigakis | ('st_mode', c_mode_t),
|
56 | 49350be7 | Giorgos Verigakis | ('st_nlink', c_uint16),
|
57 | 49350be7 | Giorgos Verigakis | ('st_uid', c_uid_t),
|
58 | 49350be7 | Giorgos Verigakis | ('st_gid', c_gid_t),
|
59 | 49350be7 | Giorgos Verigakis | ('st_rdev', c_dev_t),
|
60 | 49350be7 | Giorgos Verigakis | ('st_atimespec', c_timespec),
|
61 | 49350be7 | Giorgos Verigakis | ('st_mtimespec', c_timespec),
|
62 | 49350be7 | Giorgos Verigakis | ('st_ctimespec', c_timespec),
|
63 | 49350be7 | Giorgos Verigakis | ('st_size', c_off_t),
|
64 | 49350be7 | Giorgos Verigakis | ('st_blocks', c_int64),
|
65 | 49350be7 | Giorgos Verigakis | ('st_blksize', c_int32)]
|
66 | 49350be7 | Giorgos Verigakis | elif _system == 'Linux': |
67 | 49350be7 | Giorgos Verigakis | ENOTSUP = 95
|
68 | 49350be7 | Giorgos Verigakis | c_dev_t = c_ulonglong |
69 | 49350be7 | Giorgos Verigakis | c_fsblkcnt_t = c_ulonglong |
70 | 49350be7 | Giorgos Verigakis | c_fsfilcnt_t = c_ulonglong |
71 | 49350be7 | Giorgos Verigakis | c_gid_t = c_uint |
72 | 49350be7 | Giorgos Verigakis | c_mode_t = c_uint |
73 | 49350be7 | Giorgos Verigakis | c_off_t = c_longlong |
74 | 49350be7 | Giorgos Verigakis | c_pid_t = c_int |
75 | 49350be7 | Giorgos Verigakis | c_uid_t = c_uint |
76 | 49350be7 | Giorgos Verigakis | setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int) |
77 | 49350be7 | Giorgos Verigakis | getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t) |
78 | 49350be7 | Giorgos Verigakis | |
79 | 49350be7 | Giorgos Verigakis | _machine = machine() |
80 | 49350be7 | Giorgos Verigakis | if _machine == 'x86_64': |
81 | 49350be7 | Giorgos Verigakis | c_stat._fields_ = [ |
82 | 49350be7 | Giorgos Verigakis | ('st_dev', c_dev_t),
|
83 | 49350be7 | Giorgos Verigakis | ('st_ino', c_ulong),
|
84 | 49350be7 | Giorgos Verigakis | ('st_nlink', c_ulong),
|
85 | 49350be7 | Giorgos Verigakis | ('st_mode', c_mode_t),
|
86 | 49350be7 | Giorgos Verigakis | ('st_uid', c_uid_t),
|
87 | 49350be7 | Giorgos Verigakis | ('st_gid', c_gid_t),
|
88 | 49350be7 | Giorgos Verigakis | ('__pad0', c_int),
|
89 | 49350be7 | Giorgos Verigakis | ('st_rdev', c_dev_t),
|
90 | 49350be7 | Giorgos Verigakis | ('st_size', c_off_t),
|
91 | 49350be7 | Giorgos Verigakis | ('st_blksize', c_long),
|
92 | 49350be7 | Giorgos Verigakis | ('st_blocks', c_long),
|
93 | 49350be7 | Giorgos Verigakis | ('st_atimespec', c_timespec),
|
94 | 49350be7 | Giorgos Verigakis | ('st_mtimespec', c_timespec),
|
95 | 49350be7 | Giorgos Verigakis | ('st_ctimespec', c_timespec)]
|
96 | 49350be7 | Giorgos Verigakis | elif _machine == 'ppc': |
97 | 49350be7 | Giorgos Verigakis | c_stat._fields_ = [ |
98 | 49350be7 | Giorgos Verigakis | ('st_dev', c_dev_t),
|
99 | 49350be7 | Giorgos Verigakis | ('st_ino', c_ulonglong),
|
100 | 49350be7 | Giorgos Verigakis | ('st_mode', c_mode_t),
|
101 | 49350be7 | Giorgos Verigakis | ('st_nlink', c_uint),
|
102 | 49350be7 | Giorgos Verigakis | ('st_uid', c_uid_t),
|
103 | 49350be7 | Giorgos Verigakis | ('st_gid', c_gid_t),
|
104 | 49350be7 | Giorgos Verigakis | ('st_rdev', c_dev_t),
|
105 | 49350be7 | Giorgos Verigakis | ('__pad2', c_ushort),
|
106 | 49350be7 | Giorgos Verigakis | ('st_size', c_off_t),
|
107 | 49350be7 | Giorgos Verigakis | ('st_blksize', c_long),
|
108 | 49350be7 | Giorgos Verigakis | ('st_blocks', c_longlong),
|
109 | 49350be7 | Giorgos Verigakis | ('st_atimespec', c_timespec),
|
110 | 49350be7 | Giorgos Verigakis | ('st_mtimespec', c_timespec),
|
111 | 49350be7 | Giorgos Verigakis | ('st_ctimespec', c_timespec)]
|
112 | 49350be7 | Giorgos Verigakis | else:
|
113 | 49350be7 | Giorgos Verigakis | # i686, use as fallback for everything else
|
114 | 49350be7 | Giorgos Verigakis | c_stat._fields_ = [ |
115 | 49350be7 | Giorgos Verigakis | ('st_dev', c_dev_t),
|
116 | 49350be7 | Giorgos Verigakis | ('__pad1', c_ushort),
|
117 | 49350be7 | Giorgos Verigakis | ('__st_ino', c_ulong),
|
118 | 49350be7 | Giorgos Verigakis | ('st_mode', c_mode_t),
|
119 | 49350be7 | Giorgos Verigakis | ('st_nlink', c_uint),
|
120 | 49350be7 | Giorgos Verigakis | ('st_uid', c_uid_t),
|
121 | 49350be7 | Giorgos Verigakis | ('st_gid', c_gid_t),
|
122 | 49350be7 | Giorgos Verigakis | ('st_rdev', c_dev_t),
|
123 | 49350be7 | Giorgos Verigakis | ('__pad2', c_ushort),
|
124 | 49350be7 | Giorgos Verigakis | ('st_size', c_off_t),
|
125 | 49350be7 | Giorgos Verigakis | ('st_blksize', c_long),
|
126 | 49350be7 | Giorgos Verigakis | ('st_blocks', c_longlong),
|
127 | 49350be7 | Giorgos Verigakis | ('st_atimespec', c_timespec),
|
128 | 49350be7 | Giorgos Verigakis | ('st_mtimespec', c_timespec),
|
129 | 49350be7 | Giorgos Verigakis | ('st_ctimespec', c_timespec),
|
130 | 49350be7 | Giorgos Verigakis | ('st_ino', c_ulonglong)]
|
131 | 49350be7 | Giorgos Verigakis | else:
|
132 | 49350be7 | Giorgos Verigakis | raise NotImplementedError('%s is not supported.' % _system) |
133 | 49350be7 | Giorgos Verigakis | |
134 | 49350be7 | Giorgos Verigakis | |
135 | 49350be7 | Giorgos Verigakis | class c_statvfs(Structure): |
136 | 49350be7 | Giorgos Verigakis | _fields_ = [ |
137 | 49350be7 | Giorgos Verigakis | ('f_bsize', c_ulong),
|
138 | 49350be7 | Giorgos Verigakis | ('f_frsize', c_ulong),
|
139 | 49350be7 | Giorgos Verigakis | ('f_blocks', c_fsblkcnt_t),
|
140 | 49350be7 | Giorgos Verigakis | ('f_bfree', c_fsblkcnt_t),
|
141 | 49350be7 | Giorgos Verigakis | ('f_bavail', c_fsblkcnt_t),
|
142 | 49350be7 | Giorgos Verigakis | ('f_files', c_fsfilcnt_t),
|
143 | 49350be7 | Giorgos Verigakis | ('f_ffree', c_fsfilcnt_t),
|
144 | 49350be7 | Giorgos Verigakis | ('f_favail', c_fsfilcnt_t)]
|
145 | 49350be7 | Giorgos Verigakis | |
146 | 49350be7 | Giorgos Verigakis | if _system == 'FreeBSD': |
147 | 49350be7 | Giorgos Verigakis | c_fsblkcnt_t = c_uint64 |
148 | 49350be7 | Giorgos Verigakis | c_fsfilcnt_t = c_uint64 |
149 | 49350be7 | Giorgos Verigakis | setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int) |
150 | 49350be7 | Giorgos Verigakis | getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t) |
151 | 49350be7 | Giorgos Verigakis | class c_statvfs(Structure): |
152 | 49350be7 | Giorgos Verigakis | _fields_ = [ |
153 | 49350be7 | Giorgos Verigakis | ('f_bavail', c_fsblkcnt_t),
|
154 | 49350be7 | Giorgos Verigakis | ('f_bfree', c_fsblkcnt_t),
|
155 | 49350be7 | Giorgos Verigakis | ('f_blocks', c_fsblkcnt_t),
|
156 | 49350be7 | Giorgos Verigakis | ('f_favail', c_fsfilcnt_t),
|
157 | 49350be7 | Giorgos Verigakis | ('f_ffree', c_fsfilcnt_t),
|
158 | 49350be7 | Giorgos Verigakis | ('f_files', c_fsfilcnt_t),
|
159 | 49350be7 | Giorgos Verigakis | ('f_bsize', c_ulong),
|
160 | 49350be7 | Giorgos Verigakis | ('f_flag', c_ulong),
|
161 | 49350be7 | Giorgos Verigakis | ('f_frsize', c_ulong)]
|
162 | 49350be7 | Giorgos Verigakis | |
163 | 49350be7 | Giorgos Verigakis | class fuse_file_info(Structure): |
164 | 49350be7 | Giorgos Verigakis | _fields_ = [ |
165 | 49350be7 | Giorgos Verigakis | ('flags', c_int),
|
166 | 49350be7 | Giorgos Verigakis | ('fh_old', c_ulong),
|
167 | 49350be7 | Giorgos Verigakis | ('writepage', c_int),
|
168 | 49350be7 | Giorgos Verigakis | ('direct_io', c_uint, 1), |
169 | 49350be7 | Giorgos Verigakis | ('keep_cache', c_uint, 1), |
170 | 49350be7 | Giorgos Verigakis | ('flush', c_uint, 1), |
171 | 49350be7 | Giorgos Verigakis | ('padding', c_uint, 29), |
172 | 49350be7 | Giorgos Verigakis | ('fh', c_uint64),
|
173 | 49350be7 | Giorgos Verigakis | ('lock_owner', c_uint64)]
|
174 | 49350be7 | Giorgos Verigakis | |
175 | 49350be7 | Giorgos Verigakis | class fuse_context(Structure): |
176 | 49350be7 | Giorgos Verigakis | _fields_ = [ |
177 | 49350be7 | Giorgos Verigakis | ('fuse', c_voidp),
|
178 | 49350be7 | Giorgos Verigakis | ('uid', c_uid_t),
|
179 | 49350be7 | Giorgos Verigakis | ('gid', c_gid_t),
|
180 | 49350be7 | Giorgos Verigakis | ('pid', c_pid_t),
|
181 | 49350be7 | Giorgos Verigakis | ('private_data', c_voidp)]
|
182 | 49350be7 | Giorgos Verigakis | |
183 | 49350be7 | Giorgos Verigakis | class fuse_operations(Structure): |
184 | 49350be7 | Giorgos Verigakis | _fields_ = [ |
185 | 49350be7 | Giorgos Verigakis | ('getattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat))),
|
186 | 49350be7 | Giorgos Verigakis | ('readlink', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t)),
|
187 | 49350be7 | Giorgos Verigakis | ('getdir', c_voidp), # Deprecated, use readdir |
188 | 49350be7 | Giorgos Verigakis | ('mknod', CFUNCTYPE(c_int, c_char_p, c_mode_t, c_dev_t)),
|
189 | 49350be7 | Giorgos Verigakis | ('mkdir', CFUNCTYPE(c_int, c_char_p, c_mode_t)),
|
190 | 49350be7 | Giorgos Verigakis | ('unlink', CFUNCTYPE(c_int, c_char_p)),
|
191 | 49350be7 | Giorgos Verigakis | ('rmdir', CFUNCTYPE(c_int, c_char_p)),
|
192 | 49350be7 | Giorgos Verigakis | ('symlink', CFUNCTYPE(c_int, c_char_p, c_char_p)),
|
193 | 49350be7 | Giorgos Verigakis | ('rename', CFUNCTYPE(c_int, c_char_p, c_char_p)),
|
194 | 49350be7 | Giorgos Verigakis | ('link', CFUNCTYPE(c_int, c_char_p, c_char_p)),
|
195 | 49350be7 | Giorgos Verigakis | ('chmod', CFUNCTYPE(c_int, c_char_p, c_mode_t)),
|
196 | 49350be7 | Giorgos Verigakis | ('chown', CFUNCTYPE(c_int, c_char_p, c_uid_t, c_gid_t)),
|
197 | 49350be7 | Giorgos Verigakis | ('truncate', CFUNCTYPE(c_int, c_char_p, c_off_t)),
|
198 | 49350be7 | Giorgos Verigakis | ('utime', c_voidp), # Deprecated, use utimens |
199 | 49350be7 | Giorgos Verigakis | ('open', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
|
200 | 49350be7 | Giorgos Verigakis | ('read', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t,
|
201 | 49350be7 | Giorgos Verigakis | POINTER(fuse_file_info))), |
202 | 49350be7 | Giorgos Verigakis | ('write', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t,
|
203 | 49350be7 | Giorgos Verigakis | POINTER(fuse_file_info))), |
204 | 49350be7 | Giorgos Verigakis | ('statfs', CFUNCTYPE(c_int, c_char_p, POINTER(c_statvfs))),
|
205 | 49350be7 | Giorgos Verigakis | ('flush', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
|
206 | 49350be7 | Giorgos Verigakis | ('release', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
|
207 | 49350be7 | Giorgos Verigakis | ('fsync', CFUNCTYPE(c_int, c_char_p, c_int, POINTER(fuse_file_info))),
|
208 | 49350be7 | Giorgos Verigakis | ('setxattr', setxattr_t),
|
209 | 49350be7 | Giorgos Verigakis | ('getxattr', getxattr_t),
|
210 | 49350be7 | Giorgos Verigakis | ('listxattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t)),
|
211 | 49350be7 | Giorgos Verigakis | ('removexattr', CFUNCTYPE(c_int, c_char_p, c_char_p)),
|
212 | 49350be7 | Giorgos Verigakis | ('opendir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
|
213 | 49350be7 | Giorgos Verigakis | ('readdir', CFUNCTYPE(c_int, c_char_p, c_voidp, CFUNCTYPE(c_int, c_voidp,
|
214 | 49350be7 | Giorgos Verigakis | c_char_p, POINTER(c_stat), c_off_t), c_off_t, POINTER(fuse_file_info))), |
215 | 49350be7 | Giorgos Verigakis | ('releasedir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
|
216 | 49350be7 | Giorgos Verigakis | ('fsyncdir', CFUNCTYPE(c_int, c_char_p, c_int, POINTER(fuse_file_info))),
|
217 | 49350be7 | Giorgos Verigakis | ('init', CFUNCTYPE(c_voidp, c_voidp)),
|
218 | 49350be7 | Giorgos Verigakis | ('destroy', CFUNCTYPE(c_voidp, c_voidp)),
|
219 | 49350be7 | Giorgos Verigakis | ('access', CFUNCTYPE(c_int, c_char_p, c_int)),
|
220 | 49350be7 | Giorgos Verigakis | ('create', CFUNCTYPE(c_int, c_char_p, c_mode_t, POINTER(fuse_file_info))),
|
221 | 49350be7 | Giorgos Verigakis | ('ftruncate', CFUNCTYPE(c_int, c_char_p, c_off_t, POINTER(fuse_file_info))),
|
222 | 49350be7 | Giorgos Verigakis | ('fgetattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat),
|
223 | 49350be7 | Giorgos Verigakis | POINTER(fuse_file_info))), |
224 | 49350be7 | Giorgos Verigakis | ('lock', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info), c_int, c_voidp)),
|
225 | 49350be7 | Giorgos Verigakis | ('utimens', CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))),
|
226 | 49350be7 | Giorgos Verigakis | ('bmap', CFUNCTYPE(c_int, c_char_p, c_size_t, POINTER(c_ulonglong)))]
|
227 | 49350be7 | Giorgos Verigakis | |
228 | 49350be7 | Giorgos Verigakis | |
229 | 49350be7 | Giorgos Verigakis | def time_of_timespec(ts): |
230 | 49350be7 | Giorgos Verigakis | return ts.tv_sec + ts.tv_nsec / 10 ** 9 |
231 | 49350be7 | Giorgos Verigakis | |
232 | 49350be7 | Giorgos Verigakis | def set_st_attrs(st, attrs): |
233 | 49350be7 | Giorgos Verigakis | for key, val in attrs.items(): |
234 | 49350be7 | Giorgos Verigakis | if key in ('st_atime', 'st_mtime', 'st_ctime'): |
235 | 49350be7 | Giorgos Verigakis | timespec = getattr(st, key + 'spec') |
236 | 49350be7 | Giorgos Verigakis | timespec.tv_sec = int(val)
|
237 | 49350be7 | Giorgos Verigakis | timespec.tv_nsec = int((val - timespec.tv_sec) * 10 ** 9) |
238 | 49350be7 | Giorgos Verigakis | elif hasattr(st, key): |
239 | 49350be7 | Giorgos Verigakis | setattr(st, key, val)
|
240 | 49350be7 | Giorgos Verigakis | |
241 | 49350be7 | Giorgos Verigakis | |
242 | 49350be7 | Giorgos Verigakis | _libfuse_path = find_library('fuse')
|
243 | 49350be7 | Giorgos Verigakis | if not _libfuse_path: |
244 | 49350be7 | Giorgos Verigakis | raise EnvironmentError('Unable to find libfuse') |
245 | 49350be7 | Giorgos Verigakis | _libfuse = CDLL(_libfuse_path) |
246 | 49350be7 | Giorgos Verigakis | _libfuse.fuse_get_context.restype = POINTER(fuse_context) |
247 | 49350be7 | Giorgos Verigakis | |
248 | 49350be7 | Giorgos Verigakis | |
249 | 49350be7 | Giorgos Verigakis | def fuse_get_context(): |
250 | 49350be7 | Giorgos Verigakis | """Returns a (uid, gid, pid) tuple"""
|
251 | 49350be7 | Giorgos Verigakis | ctxp = _libfuse.fuse_get_context() |
252 | 49350be7 | Giorgos Verigakis | ctx = ctxp.contents |
253 | 49350be7 | Giorgos Verigakis | return ctx.uid, ctx.gid, ctx.pid
|
254 | 49350be7 | Giorgos Verigakis | |
255 | 49350be7 | Giorgos Verigakis | |
256 | 49350be7 | Giorgos Verigakis | class FuseOSError(OSError): |
257 | 49350be7 | Giorgos Verigakis | def __init__(self, errno): |
258 | 49350be7 | Giorgos Verigakis | super(FuseOSError, self).__init__(errno, strerror(errno)) |
259 | 49350be7 | Giorgos Verigakis | |
260 | 49350be7 | Giorgos Verigakis | |
261 | 49350be7 | Giorgos Verigakis | class FUSE(object): |
262 | 49350be7 | Giorgos Verigakis | """This class is the lower level interface and should not be subclassed
|
263 | 49350be7 | Giorgos Verigakis | under normal use. Its methods are called by fuse.
|
264 | 49350be7 | Giorgos Verigakis | Assumes API version 2.6 or later."""
|
265 | 49350be7 | Giorgos Verigakis | |
266 | 49350be7 | Giorgos Verigakis | def __init__(self, operations, mountpoint, raw_fi=False, **kwargs): |
267 | 49350be7 | Giorgos Verigakis | """Setting raw_fi to True will cause FUSE to pass the fuse_file_info
|
268 | 49350be7 | Giorgos Verigakis | class as is to Operations, instead of just the fh field.
|
269 | 49350be7 | Giorgos Verigakis | This gives you access to direct_io, keep_cache, etc."""
|
270 | 49350be7 | Giorgos Verigakis | |
271 | 49350be7 | Giorgos Verigakis | self.operations = operations
|
272 | 49350be7 | Giorgos Verigakis | self.raw_fi = raw_fi
|
273 | 49350be7 | Giorgos Verigakis | args = ['fuse']
|
274 | 49350be7 | Giorgos Verigakis | if kwargs.pop('foreground', False): |
275 | 49350be7 | Giorgos Verigakis | args.append('-f')
|
276 | 49350be7 | Giorgos Verigakis | if kwargs.pop('debug', False): |
277 | 49350be7 | Giorgos Verigakis | args.append('-d')
|
278 | 49350be7 | Giorgos Verigakis | if kwargs.pop('nothreads', False): |
279 | 49350be7 | Giorgos Verigakis | args.append('-s')
|
280 | 49350be7 | Giorgos Verigakis | kwargs.setdefault('fsname', operations.__class__.__name__)
|
281 | 49350be7 | Giorgos Verigakis | args.append('-o')
|
282 | 49350be7 | Giorgos Verigakis | args.append(','.join(key if val == True else '%s=%s' % (key, val) |
283 | 49350be7 | Giorgos Verigakis | for key, val in kwargs.items())) |
284 | 49350be7 | Giorgos Verigakis | args.append(mountpoint) |
285 | 49350be7 | Giorgos Verigakis | argv = (c_char_p * len(args))(*args)
|
286 | 49350be7 | Giorgos Verigakis | |
287 | 49350be7 | Giorgos Verigakis | fuse_ops = fuse_operations() |
288 | 49350be7 | Giorgos Verigakis | for name, prototype in fuse_operations._fields_: |
289 | 49350be7 | Giorgos Verigakis | if prototype != c_voidp and getattr(operations, name, None): |
290 | 49350be7 | Giorgos Verigakis | op = partial(self._wrapper_, getattr(self, name)) |
291 | 49350be7 | Giorgos Verigakis | setattr(fuse_ops, name, prototype(op))
|
292 | 49350be7 | Giorgos Verigakis | err = _libfuse.fuse_main_real(len(args), argv, pointer(fuse_ops),
|
293 | 49350be7 | Giorgos Verigakis | sizeof(fuse_ops), None)
|
294 | 49350be7 | Giorgos Verigakis | del self.operations # Invoke the destructor |
295 | 49350be7 | Giorgos Verigakis | if err:
|
296 | 49350be7 | Giorgos Verigakis | raise RuntimeError(err) |
297 | 49350be7 | Giorgos Verigakis | |
298 | 49350be7 | Giorgos Verigakis | def _wrapper_(self, func, *args, **kwargs): |
299 | 49350be7 | Giorgos Verigakis | """Decorator for the methods that follow"""
|
300 | 49350be7 | Giorgos Verigakis | try:
|
301 | 49350be7 | Giorgos Verigakis | return func(*args, **kwargs) or 0 |
302 | 49350be7 | Giorgos Verigakis | except OSError, e: |
303 | 49350be7 | Giorgos Verigakis | return -(e.errno or EFAULT) |
304 | 49350be7 | Giorgos Verigakis | except:
|
305 | 49350be7 | Giorgos Verigakis | print_exc() |
306 | 49350be7 | Giorgos Verigakis | return -EFAULT
|
307 | 49350be7 | Giorgos Verigakis | |
308 | 49350be7 | Giorgos Verigakis | def getattr(self, path, buf): |
309 | 49350be7 | Giorgos Verigakis | return self.fgetattr(path, buf, None) |
310 | 49350be7 | Giorgos Verigakis | |
311 | 49350be7 | Giorgos Verigakis | def readlink(self, path, buf, bufsize): |
312 | 49350be7 | Giorgos Verigakis | ret = self.operations('readlink', path) |
313 | 49350be7 | Giorgos Verigakis | data = create_string_buffer(ret[:bufsize - 1])
|
314 | 49350be7 | Giorgos Verigakis | memmove(buf, data, len(data))
|
315 | 49350be7 | Giorgos Verigakis | return 0 |
316 | 49350be7 | Giorgos Verigakis | |
317 | 49350be7 | Giorgos Verigakis | def mknod(self, path, mode, dev): |
318 | 49350be7 | Giorgos Verigakis | return self.operations('mknod', path, mode, dev) |
319 | 49350be7 | Giorgos Verigakis | |
320 | 49350be7 | Giorgos Verigakis | def mkdir(self, path, mode): |
321 | 49350be7 | Giorgos Verigakis | return self.operations('mkdir', path, mode) |
322 | 49350be7 | Giorgos Verigakis | |
323 | 49350be7 | Giorgos Verigakis | def unlink(self, path): |
324 | 49350be7 | Giorgos Verigakis | return self.operations('unlink', path) |
325 | 49350be7 | Giorgos Verigakis | |
326 | 49350be7 | Giorgos Verigakis | def rmdir(self, path): |
327 | 49350be7 | Giorgos Verigakis | return self.operations('rmdir', path) |
328 | 49350be7 | Giorgos Verigakis | |
329 | 49350be7 | Giorgos Verigakis | def symlink(self, source, target): |
330 | 49350be7 | Giorgos Verigakis | return self.operations('symlink', target, source) |
331 | 49350be7 | Giorgos Verigakis | |
332 | 49350be7 | Giorgos Verigakis | def rename(self, old, new): |
333 | 49350be7 | Giorgos Verigakis | return self.operations('rename', old, new) |
334 | 49350be7 | Giorgos Verigakis | |
335 | 49350be7 | Giorgos Verigakis | def link(self, source, target): |
336 | 49350be7 | Giorgos Verigakis | return self.operations('link', target, source) |
337 | 49350be7 | Giorgos Verigakis | |
338 | 49350be7 | Giorgos Verigakis | def chmod(self, path, mode): |
339 | 49350be7 | Giorgos Verigakis | return self.operations('chmod', path, mode) |
340 | 49350be7 | Giorgos Verigakis | |
341 | 49350be7 | Giorgos Verigakis | def chown(self, path, uid, gid): |
342 | 49350be7 | Giorgos Verigakis | # Check if any of the arguments is a -1 that has overflowed
|
343 | 49350be7 | Giorgos Verigakis | if c_uid_t(uid + 1).value == 0: |
344 | 49350be7 | Giorgos Verigakis | uid = -1
|
345 | 49350be7 | Giorgos Verigakis | if c_gid_t(gid + 1).value == 0: |
346 | 49350be7 | Giorgos Verigakis | gid = -1
|
347 | 49350be7 | Giorgos Verigakis | return self.operations('chown', path, uid, gid) |
348 | 49350be7 | Giorgos Verigakis | |
349 | 49350be7 | Giorgos Verigakis | def truncate(self, path, length): |
350 | 49350be7 | Giorgos Verigakis | return self.operations('truncate', path, length) |
351 | 49350be7 | Giorgos Verigakis | |
352 | 49350be7 | Giorgos Verigakis | def open(self, path, fip): |
353 | 49350be7 | Giorgos Verigakis | fi = fip.contents |
354 | 49350be7 | Giorgos Verigakis | if self.raw_fi: |
355 | 49350be7 | Giorgos Verigakis | return self.operations('open', path, fi) |
356 | 49350be7 | Giorgos Verigakis | else:
|
357 | 49350be7 | Giorgos Verigakis | fi.fh = self.operations('open', path, fi.flags) |
358 | 49350be7 | Giorgos Verigakis | return 0 |
359 | 49350be7 | Giorgos Verigakis | |
360 | 49350be7 | Giorgos Verigakis | def read(self, path, buf, size, offset, fip): |
361 | 49350be7 | Giorgos Verigakis | fh = fip.contents if self.raw_fi else fip.contents.fh |
362 | 49350be7 | Giorgos Verigakis | ret = self.operations('read', path, size, offset, fh) |
363 | 49350be7 | Giorgos Verigakis | if not ret: |
364 | 49350be7 | Giorgos Verigakis | return 0 |
365 | 49350be7 | Giorgos Verigakis | data = create_string_buffer(ret[:size], size) |
366 | 49350be7 | Giorgos Verigakis | memmove(buf, data, size) |
367 | 49350be7 | Giorgos Verigakis | return size
|
368 | 49350be7 | Giorgos Verigakis | |
369 | 49350be7 | Giorgos Verigakis | def write(self, path, buf, size, offset, fip): |
370 | 49350be7 | Giorgos Verigakis | data = string_at(buf, size) |
371 | 49350be7 | Giorgos Verigakis | fh = fip.contents if self.raw_fi else fip.contents.fh |
372 | 49350be7 | Giorgos Verigakis | return self.operations('write', path, data, offset, fh) |
373 | 49350be7 | Giorgos Verigakis | |
374 | 49350be7 | Giorgos Verigakis | def statfs(self, path, buf): |
375 | 49350be7 | Giorgos Verigakis | stv = buf.contents |
376 | 49350be7 | Giorgos Verigakis | attrs = self.operations('statfs', path) |
377 | 49350be7 | Giorgos Verigakis | for key, val in attrs.items(): |
378 | 49350be7 | Giorgos Verigakis | if hasattr(stv, key): |
379 | 49350be7 | Giorgos Verigakis | setattr(stv, key, val)
|
380 | 49350be7 | Giorgos Verigakis | return 0 |
381 | 49350be7 | Giorgos Verigakis | |
382 | 49350be7 | Giorgos Verigakis | def flush(self, path, fip): |
383 | 49350be7 | Giorgos Verigakis | fh = fip.contents if self.raw_fi else fip.contents.fh |
384 | 49350be7 | Giorgos Verigakis | return self.operations('flush', path, fh) |
385 | 49350be7 | Giorgos Verigakis | |
386 | 49350be7 | Giorgos Verigakis | def release(self, path, fip): |
387 | 49350be7 | Giorgos Verigakis | fh = fip.contents if self.raw_fi else fip.contents.fh |
388 | 49350be7 | Giorgos Verigakis | return self.operations('release', path, fh) |
389 | 49350be7 | Giorgos Verigakis | |
390 | 49350be7 | Giorgos Verigakis | def fsync(self, path, datasync, fip): |
391 | 49350be7 | Giorgos Verigakis | fh = fip.contents if self.raw_fi else fip.contents.fh |
392 | 49350be7 | Giorgos Verigakis | return self.operations('fsync', path, datasync, fh) |
393 | 49350be7 | Giorgos Verigakis | |
394 | 49350be7 | Giorgos Verigakis | def setxattr(self, path, name, value, size, options, *args): |
395 | 49350be7 | Giorgos Verigakis | data = string_at(value, size) |
396 | 49350be7 | Giorgos Verigakis | return self.operations('setxattr', path, name, data, options, *args) |
397 | 49350be7 | Giorgos Verigakis | |
398 | 49350be7 | Giorgos Verigakis | def getxattr(self, path, name, value, size, *args): |
399 | 49350be7 | Giorgos Verigakis | ret = self.operations('getxattr', path, name, *args) |
400 | 49350be7 | Giorgos Verigakis | retsize = len(ret)
|
401 | 49350be7 | Giorgos Verigakis | buf = create_string_buffer(ret, retsize) # Does not add trailing 0
|
402 | 49350be7 | Giorgos Verigakis | if bool(value): |
403 | 49350be7 | Giorgos Verigakis | if retsize > size:
|
404 | 49350be7 | Giorgos Verigakis | return -ERANGE
|
405 | 49350be7 | Giorgos Verigakis | memmove(value, buf, retsize) |
406 | 49350be7 | Giorgos Verigakis | return retsize
|
407 | 49350be7 | Giorgos Verigakis | |
408 | 49350be7 | Giorgos Verigakis | def listxattr(self, path, namebuf, size): |
409 | 49350be7 | Giorgos Verigakis | ret = self.operations('listxattr', path) |
410 | 49350be7 | Giorgos Verigakis | buf = create_string_buffer('\x00'.join(ret)) if ret else '' |
411 | 49350be7 | Giorgos Verigakis | bufsize = len(buf)
|
412 | 49350be7 | Giorgos Verigakis | if bool(namebuf): |
413 | 49350be7 | Giorgos Verigakis | if bufsize > size:
|
414 | 49350be7 | Giorgos Verigakis | return -ERANGE
|
415 | 49350be7 | Giorgos Verigakis | memmove(namebuf, buf, bufsize) |
416 | 49350be7 | Giorgos Verigakis | return bufsize
|
417 | 49350be7 | Giorgos Verigakis | |
418 | 49350be7 | Giorgos Verigakis | def removexattr(self, path, name): |
419 | 49350be7 | Giorgos Verigakis | return self.operations('removexattr', path, name) |
420 | 49350be7 | Giorgos Verigakis | |
421 | 49350be7 | Giorgos Verigakis | def opendir(self, path, fip): |
422 | 49350be7 | Giorgos Verigakis | # Ignore raw_fi
|
423 | 49350be7 | Giorgos Verigakis | fip.contents.fh = self.operations('opendir', path) |
424 | 49350be7 | Giorgos Verigakis | return 0 |
425 | 49350be7 | Giorgos Verigakis | |
426 | 49350be7 | Giorgos Verigakis | def readdir(self, path, buf, filler, offset, fip): |
427 | 49350be7 | Giorgos Verigakis | # Ignore raw_fi
|
428 | 49350be7 | Giorgos Verigakis | for item in self.operations('readdir', path, fip.contents.fh): |
429 | 49350be7 | Giorgos Verigakis | if isinstance(item, (str, unicode)): |
430 | 49350be7 | Giorgos Verigakis | name, st, offset = item, None, 0 |
431 | 49350be7 | Giorgos Verigakis | else:
|
432 | 49350be7 | Giorgos Verigakis | name, attrs, offset = item |
433 | 49350be7 | Giorgos Verigakis | if attrs:
|
434 | 49350be7 | Giorgos Verigakis | st = c_stat() |
435 | 49350be7 | Giorgos Verigakis | set_st_attrs(st, attrs) |
436 | 49350be7 | Giorgos Verigakis | else:
|
437 | 49350be7 | Giorgos Verigakis | st = None
|
438 | 49350be7 | Giorgos Verigakis | if filler(buf, name, st, offset) != 0: |
439 | 49350be7 | Giorgos Verigakis | break
|
440 | 49350be7 | Giorgos Verigakis | return 0 |
441 | 49350be7 | Giorgos Verigakis | |
442 | 49350be7 | Giorgos Verigakis | def releasedir(self, path, fip): |
443 | 49350be7 | Giorgos Verigakis | # Ignore raw_fi
|
444 | 49350be7 | Giorgos Verigakis | return self.operations('releasedir', path, fip.contents.fh) |
445 | 49350be7 | Giorgos Verigakis | |
446 | 49350be7 | Giorgos Verigakis | def fsyncdir(self, path, datasync, fip): |
447 | 49350be7 | Giorgos Verigakis | # Ignore raw_fi
|
448 | 49350be7 | Giorgos Verigakis | return self.operations('fsyncdir', path, datasync, fip.contents.fh) |
449 | 49350be7 | Giorgos Verigakis | |
450 | 49350be7 | Giorgos Verigakis | def init(self, conn): |
451 | 49350be7 | Giorgos Verigakis | return self.operations('init', '/') |
452 | 49350be7 | Giorgos Verigakis | |
453 | 49350be7 | Giorgos Verigakis | def destroy(self, private_data): |
454 | 49350be7 | Giorgos Verigakis | return self.operations('destroy', '/') |
455 | 49350be7 | Giorgos Verigakis | |
456 | 49350be7 | Giorgos Verigakis | def access(self, path, amode): |
457 | 49350be7 | Giorgos Verigakis | return self.operations('access', path, amode) |
458 | 49350be7 | Giorgos Verigakis | |
459 | 49350be7 | Giorgos Verigakis | def create(self, path, mode, fip): |
460 | 49350be7 | Giorgos Verigakis | fi = fip.contents |
461 | 49350be7 | Giorgos Verigakis | if self.raw_fi: |
462 | 49350be7 | Giorgos Verigakis | return self.operations('create', path, mode, fi) |
463 | 49350be7 | Giorgos Verigakis | else:
|
464 | 49350be7 | Giorgos Verigakis | fi.fh = self.operations('create', path, mode) |
465 | 49350be7 | Giorgos Verigakis | return 0 |
466 | 49350be7 | Giorgos Verigakis | |
467 | 49350be7 | Giorgos Verigakis | def ftruncate(self, path, length, fip): |
468 | 49350be7 | Giorgos Verigakis | fh = fip.contents if self.raw_fi else fip.contents.fh |
469 | 49350be7 | Giorgos Verigakis | return self.operations('truncate', path, length, fh) |
470 | 49350be7 | Giorgos Verigakis | |
471 | 49350be7 | Giorgos Verigakis | def fgetattr(self, path, buf, fip): |
472 | 49350be7 | Giorgos Verigakis | memset(buf, 0, sizeof(c_stat))
|
473 | 49350be7 | Giorgos Verigakis | st = buf.contents |
474 | 49350be7 | Giorgos Verigakis | fh = fip and (fip.contents if self.raw_fi else fip.contents.fh) |
475 | 49350be7 | Giorgos Verigakis | attrs = self.operations('getattr', path, fh) |
476 | 49350be7 | Giorgos Verigakis | set_st_attrs(st, attrs) |
477 | 49350be7 | Giorgos Verigakis | return 0 |
478 | 49350be7 | Giorgos Verigakis | |
479 | 49350be7 | Giorgos Verigakis | def lock(self, path, fip, cmd, lock): |
480 | 49350be7 | Giorgos Verigakis | fh = fip.contents if self.raw_fi else fip.contents.fh |
481 | 49350be7 | Giorgos Verigakis | return self.operations('lock', path, fh, cmd, lock) |
482 | 49350be7 | Giorgos Verigakis | |
483 | 49350be7 | Giorgos Verigakis | def utimens(self, path, buf): |
484 | 49350be7 | Giorgos Verigakis | if buf:
|
485 | 49350be7 | Giorgos Verigakis | atime = time_of_timespec(buf.contents.actime) |
486 | 49350be7 | Giorgos Verigakis | mtime = time_of_timespec(buf.contents.modtime) |
487 | 49350be7 | Giorgos Verigakis | times = (atime, mtime) |
488 | 49350be7 | Giorgos Verigakis | else:
|
489 | 49350be7 | Giorgos Verigakis | times = None
|
490 | 49350be7 | Giorgos Verigakis | return self.operations('utimens', path, times) |
491 | 49350be7 | Giorgos Verigakis | |
492 | 49350be7 | Giorgos Verigakis | def bmap(self, path, blocksize, idx): |
493 | 49350be7 | Giorgos Verigakis | return self.operations('bmap', path, blocksize, idx) |
494 | 49350be7 | Giorgos Verigakis | |
495 | 49350be7 | Giorgos Verigakis | |
496 | 49350be7 | Giorgos Verigakis | class Operations(object): |
497 | 49350be7 | Giorgos Verigakis | """This class should be subclassed and passed as an argument to FUSE on
|
498 | 49350be7 | Giorgos Verigakis | initialization. All operations should raise a FuseOSError exception
|
499 | 49350be7 | Giorgos Verigakis | on error.
|
500 | 49350be7 | Giorgos Verigakis |
|
501 | 49350be7 | Giorgos Verigakis | When in doubt of what an operation should do, check the FUSE header
|
502 | 49350be7 | Giorgos Verigakis | file or the corresponding system call man page."""
|
503 | 49350be7 | Giorgos Verigakis | |
504 | 49350be7 | Giorgos Verigakis | def __call__(self, op, *args): |
505 | 49350be7 | Giorgos Verigakis | if not hasattr(self, op): |
506 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EFAULT)
|
507 | 49350be7 | Giorgos Verigakis | return getattr(self, op)(*args) |
508 | 49350be7 | Giorgos Verigakis | |
509 | 49350be7 | Giorgos Verigakis | def access(self, path, amode): |
510 | 49350be7 | Giorgos Verigakis | return 0 |
511 | 49350be7 | Giorgos Verigakis | |
512 | 49350be7 | Giorgos Verigakis | bmap = None
|
513 | 49350be7 | Giorgos Verigakis | |
514 | 49350be7 | Giorgos Verigakis | def chmod(self, path, mode): |
515 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
516 | 49350be7 | Giorgos Verigakis | |
517 | 49350be7 | Giorgos Verigakis | def chown(self, path, uid, gid): |
518 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
519 | 49350be7 | Giorgos Verigakis | |
520 | 49350be7 | Giorgos Verigakis | def create(self, path, mode, fi=None): |
521 | 49350be7 | Giorgos Verigakis | """When raw_fi is False (default case), fi is None and create should
|
522 | 49350be7 | Giorgos Verigakis | return a numerical file handle.
|
523 | 49350be7 | Giorgos Verigakis | When raw_fi is True the file handle should be set directly by create
|
524 | 49350be7 | Giorgos Verigakis | and return 0."""
|
525 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
526 | 49350be7 | Giorgos Verigakis | |
527 | 49350be7 | Giorgos Verigakis | def destroy(self, path): |
528 | 49350be7 | Giorgos Verigakis | """Called on filesystem destruction. Path is always /"""
|
529 | 49350be7 | Giorgos Verigakis | pass
|
530 | 49350be7 | Giorgos Verigakis | |
531 | 49350be7 | Giorgos Verigakis | def flush(self, path, fh): |
532 | 49350be7 | Giorgos Verigakis | return 0 |
533 | 49350be7 | Giorgos Verigakis | |
534 | 49350be7 | Giorgos Verigakis | def fsync(self, path, datasync, fh): |
535 | 49350be7 | Giorgos Verigakis | return 0 |
536 | 49350be7 | Giorgos Verigakis | |
537 | 49350be7 | Giorgos Verigakis | def fsyncdir(self, path, datasync, fh): |
538 | 49350be7 | Giorgos Verigakis | return 0 |
539 | 49350be7 | Giorgos Verigakis | |
540 | 49350be7 | Giorgos Verigakis | def getattr(self, path, fh=None): |
541 | 49350be7 | Giorgos Verigakis | """Returns a dictionary with keys identical to the stat C structure
|
542 | 49350be7 | Giorgos Verigakis | of stat(2).
|
543 | 49350be7 | Giorgos Verigakis | st_atime, st_mtime and st_ctime should be floats.
|
544 | 49350be7 | Giorgos Verigakis | NOTE: There is an incombatibility between Linux and Mac OS X concerning
|
545 | 49350be7 | Giorgos Verigakis | st_nlink of directories. Mac OS X counts all files inside the directory,
|
546 | 49350be7 | Giorgos Verigakis | while Linux counts only the subdirectories."""
|
547 | 49350be7 | Giorgos Verigakis | |
548 | 49350be7 | Giorgos Verigakis | if path != '/': |
549 | 49350be7 | Giorgos Verigakis | raise FuseOSError(ENOENT)
|
550 | 49350be7 | Giorgos Verigakis | return dict(st_mode=(S_IFDIR | 0755), st_nlink=2) |
551 | 49350be7 | Giorgos Verigakis | |
552 | 49350be7 | Giorgos Verigakis | def getxattr(self, path, name, position=0): |
553 | 49350be7 | Giorgos Verigakis | raise FuseOSError(ENOTSUP)
|
554 | 49350be7 | Giorgos Verigakis | |
555 | 49350be7 | Giorgos Verigakis | def init(self, path): |
556 | 49350be7 | Giorgos Verigakis | """Called on filesystem initialization. Path is always /
|
557 | 49350be7 | Giorgos Verigakis | Use it instead of __init__ if you start threads on initialization."""
|
558 | 49350be7 | Giorgos Verigakis | pass
|
559 | 49350be7 | Giorgos Verigakis | |
560 | 49350be7 | Giorgos Verigakis | def link(self, target, source): |
561 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
562 | 49350be7 | Giorgos Verigakis | |
563 | 49350be7 | Giorgos Verigakis | def listxattr(self, path): |
564 | 49350be7 | Giorgos Verigakis | return []
|
565 | 49350be7 | Giorgos Verigakis | |
566 | 49350be7 | Giorgos Verigakis | lock = None
|
567 | 49350be7 | Giorgos Verigakis | |
568 | 49350be7 | Giorgos Verigakis | def mkdir(self, path, mode): |
569 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
570 | 49350be7 | Giorgos Verigakis | |
571 | 49350be7 | Giorgos Verigakis | def mknod(self, path, mode, dev): |
572 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
573 | 49350be7 | Giorgos Verigakis | |
574 | 49350be7 | Giorgos Verigakis | def open(self, path, flags): |
575 | 49350be7 | Giorgos Verigakis | """When raw_fi is False (default case), open should return a numerical
|
576 | 49350be7 | Giorgos Verigakis | file handle.
|
577 | 49350be7 | Giorgos Verigakis | When raw_fi is True the signature of open becomes:
|
578 | 49350be7 | Giorgos Verigakis | open(self, path, fi)
|
579 | 49350be7 | Giorgos Verigakis | and the file handle should be set directly."""
|
580 | 49350be7 | Giorgos Verigakis | return 0 |
581 | 49350be7 | Giorgos Verigakis | |
582 | 49350be7 | Giorgos Verigakis | def opendir(self, path): |
583 | 49350be7 | Giorgos Verigakis | """Returns a numerical file handle."""
|
584 | 49350be7 | Giorgos Verigakis | return 0 |
585 | 49350be7 | Giorgos Verigakis | |
586 | 49350be7 | Giorgos Verigakis | def read(self, path, size, offset, fh): |
587 | 49350be7 | Giorgos Verigakis | """Returns a string containing the data requested."""
|
588 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EIO)
|
589 | 49350be7 | Giorgos Verigakis | |
590 | 49350be7 | Giorgos Verigakis | def readdir(self, path, fh): |
591 | 49350be7 | Giorgos Verigakis | """Can return either a list of names, or a list of (name, attrs, offset)
|
592 | 49350be7 | Giorgos Verigakis | tuples. attrs is a dict as in getattr."""
|
593 | 49350be7 | Giorgos Verigakis | return ['.', '..'] |
594 | 49350be7 | Giorgos Verigakis | |
595 | 49350be7 | Giorgos Verigakis | def readlink(self, path): |
596 | 49350be7 | Giorgos Verigakis | raise FuseOSError(ENOENT)
|
597 | 49350be7 | Giorgos Verigakis | |
598 | 49350be7 | Giorgos Verigakis | def release(self, path, fh): |
599 | 49350be7 | Giorgos Verigakis | return 0 |
600 | 49350be7 | Giorgos Verigakis | |
601 | 49350be7 | Giorgos Verigakis | def releasedir(self, path, fh): |
602 | 49350be7 | Giorgos Verigakis | return 0 |
603 | 49350be7 | Giorgos Verigakis | |
604 | 49350be7 | Giorgos Verigakis | def removexattr(self, path, name): |
605 | 49350be7 | Giorgos Verigakis | raise FuseOSError(ENOTSUP)
|
606 | 49350be7 | Giorgos Verigakis | |
607 | 49350be7 | Giorgos Verigakis | def rename(self, old, new): |
608 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
609 | 49350be7 | Giorgos Verigakis | |
610 | 49350be7 | Giorgos Verigakis | def rmdir(self, path): |
611 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
612 | 49350be7 | Giorgos Verigakis | |
613 | 49350be7 | Giorgos Verigakis | def setxattr(self, path, name, value, options, position=0): |
614 | 49350be7 | Giorgos Verigakis | raise FuseOSError(ENOTSUP)
|
615 | 49350be7 | Giorgos Verigakis | |
616 | 49350be7 | Giorgos Verigakis | def statfs(self, path): |
617 | 49350be7 | Giorgos Verigakis | """Returns a dictionary with keys identical to the statvfs C structure
|
618 | 49350be7 | Giorgos Verigakis | of statvfs(3).
|
619 | 49350be7 | Giorgos Verigakis | On Mac OS X f_bsize and f_frsize must be a power of 2 (minimum 512)."""
|
620 | 49350be7 | Giorgos Verigakis | return {}
|
621 | 49350be7 | Giorgos Verigakis | |
622 | 49350be7 | Giorgos Verigakis | def symlink(self, target, source): |
623 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
624 | 49350be7 | Giorgos Verigakis | |
625 | 49350be7 | Giorgos Verigakis | def truncate(self, path, length, fh=None): |
626 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
627 | 49350be7 | Giorgos Verigakis | |
628 | 49350be7 | Giorgos Verigakis | def unlink(self, path): |
629 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
630 | 49350be7 | Giorgos Verigakis | |
631 | 49350be7 | Giorgos Verigakis | def utimens(self, path, times=None): |
632 | 49350be7 | Giorgos Verigakis | """Times is a (atime, mtime) tuple. If None use current time."""
|
633 | 49350be7 | Giorgos Verigakis | return 0 |
634 | 49350be7 | Giorgos Verigakis | |
635 | 49350be7 | Giorgos Verigakis | def write(self, path, data, offset, fh): |
636 | 49350be7 | Giorgos Verigakis | raise FuseOSError(EROFS)
|
637 | 49350be7 | Giorgos Verigakis | |
638 | 49350be7 | Giorgos Verigakis | |
639 | 49350be7 | Giorgos Verigakis | class LoggingMixIn: |
640 | 49350be7 | Giorgos Verigakis | def __call__(self, op, path, *args): |
641 | 49350be7 | Giorgos Verigakis | print '->', op, path, repr(args) |
642 | 49350be7 | Giorgos Verigakis | ret = '[Unhandled Exception]'
|
643 | 49350be7 | Giorgos Verigakis | try:
|
644 | 49350be7 | Giorgos Verigakis | ret = getattr(self, op)(path, *args) |
645 | 49350be7 | Giorgos Verigakis | return ret
|
646 | 49350be7 | Giorgos Verigakis | except OSError, e: |
647 | 49350be7 | Giorgos Verigakis | ret = str(e)
|
648 | 49350be7 | Giorgos Verigakis | raise
|
649 | 49350be7 | Giorgos Verigakis | finally:
|
650 | 49350be7 | Giorgos Verigakis | print '<-', op, repr(ret) |