Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 280 lines (195 sloc) 8.935 kb
9c5307eb »
2009-09-18 first commit
1 FuseFS API DOCUMENT
2 ===================
3
4 Last updated: 2005.09.19 by Greg Millam
5
6 WARNING
7 -------
8
9 Note: If you use DirLink (in demo.rb) or in any way access a FuseFS filesystem
10 from *within* the ruby script accessing the FuseFS, then FuseFS will hang, and
11 the only recourse is a kill -KILL.
12
13 Also: If there are any open files or shells with 'pwd's in your filesystem
14 when you exit your ruby script, fuse *might* not actually be unmounted. To
15 unmount a path yourself, run the command:
16
17 fusermount -u <path>
18
19 to unmount any FUSE filesystems mounted at <path>.
20
21
22 FuseFS API
23 ----------
24
25
26 FuseFS provides a layer of abstraction to a programmer who wants to create a
27 virtual filesystem via FUSE.
28
29 FuseFS programs consist of two parts:
30
31 1) FuseFS, which is defined in 'fusefs.rb'
32 2) An object that defines a virtual directory. This must define a number of
33 methods (given below, in "Directory Methods" section) in order to be
34 usable.
35
36 To write a FuseFS program, you must:
37
38 * Define and create a Directory object that responds to the methods required
39 by FuseFS for its desired use.
40
41 * Call FuseFS.set_root <virtualdir> with the object defining your virtual
42 directory.
43
44 * Mount FuseFS under a real directory on your filesystem.
45
46 * Call FuseFS.run to start receiving and executing events.
47
48 Happy Filesystem Hacking!
49
50
51 Hello World FS
52 --------------
53 helloworld.rb
54
55 This creates a filesystem that contains exactly 1 file: "hello.txt" that, when
56 read, returns "Hello, World!"
57
58 This is not writable to, and contains no other files.
59
60 require 'fusefs'
61
62 class HelloDir
63 def contents(path)
64 ['hello.txt']
65 end
66 def file?(path)
67 path -- '/hello.txt'
68 end
69 def read_file(path)
70 "Hello, World!\n"
71 end
72 end
73
74 hellodir = HelloDir.new
75 FuseFS.set_root( hellodir )
76
77 # Mount under a directory given on the command line.
78 FuseFS.mount_under ARGV.shift
79 FuseFS.run
80
81
82 Directory Methods
83 -----------------
84
85 Without any methods defined, any object is by default a content-less,
86 file-less directory.
87
88 The following are necessary for most or all filesystems:
89
90 Directory listing and file type methods:
91
92 :contents(path) # Return an array of file and dirnames within <path>.
93 :directory?(path) # Return true if <path> is a directory.
94 :file?(path) # Return true if <path> is a file (not a directory).
95 :executable?(path) # Return true if <path> is an executable file.
96 :size(path) # Return the file size. Necessary for apache, xmms,
97 etc.
98
99 File reading:
100
101 :read_file(path) # Return the contents of the file at location <path>.
102
103 The following are only necessary if you want a filesystem that can be modified
104 by the user. Without defining any of the below, the contents of the filesystem
105 are automatically read-only.
106
107 File manipulation:
108
109 :can_write?(path) # Return true if the user can write to file at <path>.
110 :write_to(path,str) # Write the contents of <str> to file at <path>.
111
112 :can_delete?(path) # Return true if the user can delete file at <path>.
113 :delete(path) # Delete the file at <path>
114
115 Directory manipulation:
116
117 :can_mkdir?(path) # Return true if user can make a directory at <path>.
118 :mkdir(path) # Make a directory at path.
119
120 :can_rmdir?(path) # Return true if user can remove directory at <path>.
121 :rmdir(path) # Remove it.
122
123 Neat "toy":
124
125 :touch(path) # Called when a file is 'touch'd or otherwise has
126 their timestamps explicitly modified. I envision
127 this as a neat toy, maybe you can use it for a
128 push-button file?
129 "touch button" -> unmounts fusefs?
130 "touch musicfile.mp3" -> Play the mp3.
131
132 If you want a lower level control of your file, then you can use:
133
134 :raw_open(path,mode) # mode is "r" "w" or "rw", with "a" if the file
135 is opened for append. If raw_open returns true,
136 then the following calls are made:
137 :raw_read(path,off,sz) # Read sz bites from file at path starting at
138 offset off
139 :raw_write(path,off,sz,buf) # Write sz bites of buf to path starting at
140 offset off
141 :raw_close(path) # Close the file.
142
143
144 Method call flow
145 ================
146
147 List contents:
148 :directory? will be checked before :contents
149 (Most 'ls' or 'dir' functions will go on next
150 to getattr() for all contents)
151
152 Read file:
153 :file? will be checked before :read_file
154
155 Getattr
156 :directory? will be checked first.
157
158 :file? will be checked before :can_write?
159 :file? will be checked before :executable?
160
161 Writing files:
162 * directory? is usually called on the directory
163 The FS wants to write a new file to, before this
164 can occur.
165 :can_write? will be checked before :write_to
166
167 Deleting files:
168 :file? will be checked before :can_delete?
169 :can_delete? will be checked before :delete
170
171 Creating dirs:
172 * directory? is usually called on the directory
173 The FS wants to make a new directory in, before
174 this can occur.
175 :directory? will be checked.
176 :can_mkdir? is called only if :directory? is false.
177 :can_mkdir? will be checked before :mkdir
178
179 Deleting dirs:
180 :directory? will be checked before :can_rmdir?
181 :can_rmdir? will be checked before :rmdir
182
183
184 module FuseFS
185 -------------
186
187 FuseFS methods:
188
189 FuseFS.set_root(object)
190 Set the root virtual directory to <object>. All queries for obtaining
191 file information is directed at object.
192
193 FuseFS.mount_under(path[,opt[,opt,...]])
194 This will cause FuseFS to virtually mount itself under the given path.
195 'path' is required to be a valid directory in your actual filesystem.
196
197 'opt's are FUSE options. Most likely, you will only want 'allow_other'
198 or 'allow_root'. The two are mutually exclusive in FUSE, but allow_other
199 will let other users, including root, access your filesystem. allow_root
200 will only allow root to access it.
201
202 Also available for FuseFS users are:
203 default_permissions, max_read=N, fsname=NAME.
204
205 For more information, look at FUSE.
206
207 (P.S: I know FUSE allows other options, but I don't think any of the
208 rest will do any good with FuseFS. If you think otherwise, please let me
209 know!)
210
211 FuseFS.run
212 This is the final step to make your virtual filesystem accessible. It is
213 recommended you run this as your main thread, but you can thread off to
214 run this.
215
216 FuseFS.handle_editor = bool (true by default)
217 If handle_editor is true, then FuseFS will attempt to capture all editor
218 files and prevent them from being passed to FuseRoot. It also prevents
219 created and unmodified files from being passed as well, as vim (among
220 others) will attempt to create and then remove a file that does not
221 exist.
222
223 FuseFS.reader_uid and FuseFS.reader_gid
224 When the filesystem is accessed, the accessor's uid or gid is returned
225 by FuseFS.reader_uid and FuseFS.reader_gid. You can use this in
226 determining your permissions, or even provide different files for
227 different users!
228
229 FuseFS.fuse_fd and FuseFS.process
230 These are not intended for use by the programmer. If you want to muck
231 with this, read the code to see what they do :D.
232
233
234
235 FuseDir
236 ----------
237
238 FuseFS::FuseDir defines the methods "split_path" and "scan_path". You
239 should typically inherit from FuseDir in your own directory objects.
240
241 base, rest = split_path(path) # base is the file or directory in the
242 current context. rest is either nil,
243 or a path that is requested. If 'rest'
244 exists, then you should recurse the paths.
245 base, *rest = scan_path(path) # scan_path returns an array of all
246 directory and file elements given by
247 <path>. This is useful when you're
248 encapsulating an entire fs into one
249 object.
250
251 MetaDir
252 -------
253
254 MetaDir is a full filesystem defined with hashes. It is writable, and the user
255 can create and edit files within it, as well as the programmer.
256
257 Usage:
258 root = MetaDir.new
259
260 root.mkdir("/hello")
261 root.write_to("/hello/world","Hello, World!\n")
262 root.write_to("/hello/everybody","Hello, Everybody!\n")
263
264 FuseFS.set_root(root)
265
266 Because MetaDir is fully recursive, you can mount your own or other defined
267 directory structures under it. For example, to mount a dictionary filesystem
268 (as demonstrated in samples/dictfs.rb), use:
269
270 root.mkdir("/dict",DictFS.new)
271
272 Conclusion
273 ----------
274
275 Happy Hacking! If you do anything neat with this, please let me know!
276
277 My email address is walker@deafcode.com
278
279 Thanks for using FuseFS!
Something went wrong with that request. Please try again.