vfs-fsapi(n) | vfs-fsapi(n) |
vfs-fsapi - API for the implementation of a filesystem in Tcl
package require Tcl 8.4
package require vfs ?1.2.1?
vfshandler subcmd root relative actualpath args...
vfshandler access root relative actualpath mode
vfshandler createdirectory root relative actualpath
vfshandler deletefile root relative actualpath
vfshandler fileattributes root relative actualpath ?index? ?value?
vfshandler matchindirectory root relative actualpath pattern types
vfshandler open root relative actualpath mode permissions
vfshandler removedirectory root relative actualpath recursive
vfshandler stat root relative actualpath
vfshandler utime root relative actualpath actime mtime
vfs::accessMode mode
vfs::matchDirectories types
vfs::matchFiles types
vfs::matchCorrectTypes types filelist ?inDir?
This document explains the API used by the package vfs to communicate with filesystem implementations written in tcl.
The package vfs intercepts every filesystem operation which falls within a given mount point, and passes the operation on to the mount point's vfshandler command in the interpreter which registered it.
If the handler takes appropriate action for each of the cases it is called for, a complete, perfect virtual filesystem will be achieved, indistinguishable to Tcl from the native filesystem. (CAVEATS: Right now vfs does not expose to Tcl all the permission-related flags of glob).
To demonstrate the treatment of a path by the generic layer we use "C:/foo/bar/mount.zip/xxx/yyy" as an example and additionally assume that the following conditions are true:
The file separator between root and relative is omitted. Most filesystem operations need only the relative argument for their correct operation, but some actually require the other parts of the path.
The generic layer expects that the subcommands of a handler signal error conditions by calling vfs::filesystem posixerror with the appropriate posix error code instead of throwing a tcl error. If the latter is done nevertheless it will be treated as an unknown posix error.
There are three exceptions to the rule above: If any of open (when an interpreter is given), matchindirectory, and fileattributes (for a set or get operation only) throw a tcl error, this error will be passed up to the caller of the filesystem command which invoked the handler. Note that this does not preclude the ability of these subcommands to use the command vfs::filesystem posixerror to report more regular filesystem errors.
The command vfs::accessMode (see section HANDLER ENVIRONMENT) can be used to convert the integer mode into an easier to check string value.
The command has to return the value of the index'th attribute if the index is specified, but not the value. The attributes are counted in the same order as their names appear in the list returned by a call where neither index nor value were specified. The first attribute is has the index 0.
The command has to set the value of the index'th attribute to value if both index and value were specified for the call.
Note: As Tcl generates requests for directory-only matches from the filesystems involved when performing any type of recursive globbing this subcommand absolutely has to handle such (and file-only) requests correctly or bad things (TM) will happen.
The commands vfs::matchDirectories and vfs::matchFiles (see section HANDLER ENVIRONMENT) can aid the implementation greatly in this task.
The list returned upon success contains at least one and at most two elements. The first, obligatory, element is always the handle of the channel which was created to allow access to the contents of the file.
If specified the second element will be interpreted as a callback, i.e. a command prefix. This prefix will always be executed as is, i.e. without additional arguments. Any required arguments have to be returned as part of the result of the call to open.
If present the specified callback will be evaluated just before the channel is closed by the generic filesystem layer. The callback itself must not call close.
The channel however is live enough to allow seek and read operations. In addition all available data will have been flushed into it already. This means, for example, that the callback can seek to the beginning of the said channel, read its contents and then store the gathered data elsewhere. In other words, this callback is not only crucial to the cleanup of any resources associated with an opened file, but also for the ability to implement a filesystem which can be written to.
Under normal circumstances return code and any errors thrown by the callback itself are ignored. In that case errors have to be signaled asychronously, for example by calling bgerror. However if, through a call of the subcommand internalerror, an error handling script has been specified for the file system, all errors thrown here will be passed to that script for further action.
Given this the subcommand should use something like
return [list dev 0 type file mtime 1234 ...].as the last command of its implementation.
The following keys and their values have to be supplied by the filesystem:
An example of such an algorithm would be a directory walker using device/inode information to keep itself out of infinite loops generated through symbolic links. Returning non-unique device/inode information will most likely cause such a walker to skip over paths under the wrong assumption of having them seen already.
The implementation of a filesystem handler can rely on the existence of the following utility commands:
To debug a problem in the implementation of a filesystem use code as shown below. This registers the command report as the error handler for the filesystem, which in turn prints out the error stack provided by tcl.
vfs::filesystem internalerror report proc report {} {
puts stderr $::errorInfo }
vfs, vfs-filesystems
file, filesystem, vfs
Copyright (c) 2001-2003 Vince Darley <vincentdarley@users.sourceforge.net> Copyright (c) 2003 Andreas Kupries <andreas_kupries@users.sourceforge.net>
1.0 | Tcl-level Virtual Filesystems |