From b94e57c5873a1373aa47091c571ded9411cda919 Mon Sep 17 00:00:00 2001 From: Andreas Kupries Date: Wed, 12 Mar 2003 06:10:04 +0000 Subject: [PATCH] * doc/vfs.man: Added doctools documentation derived * doc/vfs-fsapi.man: from the original nroff-based * doc/vfs-filesystems.man: manpages. Approved by Vincent. --- ChangeLog | 6 + doc/vfs-filesystems.man | 95 ++++++++++ doc/vfs-fsapi.man | 403 ++++++++++++++++++++++++++++++++++++++++ doc/vfs.man | 203 ++++++++++++++++++++ 4 files changed, 707 insertions(+) create mode 100644 doc/vfs-filesystems.man create mode 100644 doc/vfs-fsapi.man create mode 100644 doc/vfs.man diff --git a/ChangeLog b/ChangeLog index d016d63..a18a287 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2003-03-11 Andreas Kupries + + * doc/vfs.man: Added doctools documentation derived + * doc/vfs-fsapi.man: from the original nroff-based + * doc/vfs-filesystems.man: manpages. Approved by Vincent. + 2003-03-11 Vince Darley * library/pkgIndex.tcl: diff --git a/doc/vfs-filesystems.man b/doc/vfs-filesystems.man new file mode 100644 index 0000000..7dee19c --- /dev/null +++ b/doc/vfs-filesystems.man @@ -0,0 +1,95 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin vfs-filesystems n 1.0] +[copyright {2001-2003 Vince Darley }] +[copyright {2003 Andreas Kupries }] +[moddesc {Tcl-level Virtual Filesystems}] +[titledesc {Filesystems provided by tclvfs}] +[require Tcl 8.4] +[require vfs [opt 1.2]] +[require vfs::zip [opt 1.0]] +[require vfs::mk4 [opt 1.6]] +[require vfs::tar [opt 0.9]] +[require vfs::ftp [opt 1.0]] +[require vfs::ns [opt 1.0]] +[require vfs::webdav [opt 0.1]] +[require vfs::http [opt 0.5]] +[require vfs::urltype [opt 1.0]] +[description] + +The package [package vfs] provides not only the means to implement a +virtual filesystem at the tcl level, but also a number of ready to be +used filesystems as well. + +[para] + +Each of these filesystem exists as its own package, and can be +accessed through [cmd {package require vfs::NAME}]. + +The whole set of these virtual filesystems is known informally as +'[term vfslib]'. + +[section {SUPPORTED VFS TYPES}] + +Currently supported are ftp, tar, http, zip, mk4, ns, and webdav. + +In addition there is the ability to mount any 'urltype' as a new +directory, provided an appropriate vfs is supported. This means that +you can treat urls based on the schmes [emph ftp://], [emph http://] +and [emph file://] as files. To do this, simply evaluate the command + +[cmd {vfs::urltype::Mount ftp}] + +for example. Any access inside the new volume will result in an +attempt to require a package through + +[cmd {package require vfs::${type}}], which must therefore exist, or +errors will be thrown. + +If a filesystem is loaded, use the associated command listed below to +mount a source for that filesystem as a tcl directory. + +[list_begin definitions] +[call [cmd vfs::zip::Mount] [arg path] [arg to]] + +Mount the zip file [arg path] as directory [arg to]. + +[call [cmd vfs::mk4::Mount] [arg path] [arg to]] + +Mount the metakit database file file [arg path] as directory [arg to]. + +[call [cmd vfs::tar::Mount] [arg path] [arg to]] + +Mount the tar file [arg path] as directory [arg to]. + +[call [cmd vfs::ftp::Mount] [arg path] [arg to]] + +Mount the ftp url [arg path] as directory [arg to]. + +[call [cmd vfs::ns::Mount] [arg path] [arg to]] + +Mount the tcl namespace [arg path] as directory [arg to]. + +[call [cmd vfs::webdav::Mount] [arg path] [arg to]] + +Mount the webdav url [arg path] as directory [arg to]. + +[call [cmd vfs::http::Mount] [arg path] [arg to]] + +Mount the http url [arg path] as directory [arg to]. + +[call [cmd vfs::urltype::Mount] [arg path] [arg to]] + +Mount the url [arg path], of type [arg urltype] as directory [arg to]. + +[list_end] + + +[section LIMITATIONS] + +Most of the vfs types listed above have not been very well debugged as +yet. Please test them! + + +[see_also vfs vfs-fsapi] +[keywords vfs filesystem file vfslib zip tar webdav ftp http namespace metakit] +[manpage_end] diff --git a/doc/vfs-fsapi.man b/doc/vfs-fsapi.man new file mode 100644 index 0000000..4a36491 --- /dev/null +++ b/doc/vfs-fsapi.man @@ -0,0 +1,403 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin vfs-fsapi n 1.0] +[copyright {2001-2003 Vince Darley }] +[copyright {2003 Andreas Kupries }] +[moddesc {Tcl-level Virtual Filesystems}] +[titledesc {API for the implementation of a filesystem in Tcl}] +[require Tcl 8.4] +[require vfs [opt 1.2]] +[description] + +This document explains the API used by the package [package vfs] +to communicate with filesystem implementations written in tcl. + +[section {HANDLER OVERVIEW}] + +The package [package vfs] intercepts every filesystem operation which +falls within a given mount point, and passes the operation on to the +mount point's [cmd vfshandler] command in the interpreter which +registered it. + +[para] + +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 [package vfs] does not expose to Tcl all the +permission-related flags of [cmd glob]). + +[para] +[list_begin definitions] + +[call [cmd vfshandler] [arg subcmd] [arg root] [arg relative] [arg actualpath] [arg args]...] + +The first argument specifies the operation to perform on behalf of the +filesystem code in the tcl core, the remainder specify the file path +on which to operate, in different forms, and parts, and any additional +arguments which may be required to carry out the action. + +[nl] + +To demonstrate the treatment of a path by the generic layer we use +[file C:/foo/bar/mount.zip/xxx/yyy] as an example and additionally +assume that the following conditions are true: + +[list_begin enum] +[enum] +[file mount.zip] is a zip archive which has been mounted on top of +itself, +[enum] +said zip archive contains a file with path [file xxx/yyy], +[enum] +the current working directory of the application is inside of +directory [file xxx], +[enum] +and the command executed is [cmd {file exists yyy}]. +[list_end] + +The file separator between [arg root] and [arg relative] is omitted. +Most filesystem operations need only the [arg relative] argument for +their correct operation, but some actually require the other parts of +the path. + + +[list_begin definitions] + +[lst_item [arg subcmd]] + +This argument of the handler can be one of the following +[method access], [method createdirectory], [method deletefile], +[method fileattributes], [method matchindirectory], [method open], +[method removedirectory], [method stat], or [method utime]. + +[nl] + +The generic layer expects that the subcommands of a handler signal +error conditions by calling [cmd {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. + +[nl] + +There are three exceptions to the rule above: If any of [method open] +(when an interpreter is given), [method matchindirectory], and + +[method 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 + +[cmd {vfs::filesystem posixerror}] to report more regular filesystem +errors. + + +[lst_item [arg root]] + +Part of the specification of the path to operate upon. It contains the +part of the path which lies outside this filesystem's mount point. For +example outlined above its value will be [file C:/foo/bar/mount.zip]. + +[lst_item [arg relative]] + +Part of the specification of the path to operate upon. It contains the +part of the path which lies inside this filesytem. For example +outlined above its value will be [file xxx/yyy]. + +[lst_item [arg actualpath]] + +Part of the specification of the path to operate upon. It contains the +original (unnormalized) name of the path which was used in the current +command wherever it originated (in Tcl or C). For example outlined +above its value will be [file yyy]. + +[list_end] +[list_end] + +[section {HANDLER METHODS}] +[list_begin definitions] + + +[call [cmd vfshandler] [method access] [arg root] [arg relative] [arg actualpath] [arg mode]] + +Signal a posix error if the specified access [arg mode] (an integer +number) is not compatible with the file or directory described by the +path. The generic layer will ignore any non-empty return value. + +[nl] + +The command [cmd vfs::accessMode] (see section + +[sectref {HANDLER ENVIRONMENT}]) can be used to convert the integer +[arg mode] into an easier to check string value. + + +[call [cmd vfshandler] [method createdirectory] [arg root] [arg relative] [arg actualpath]] + +Create a directory with the given name. The command can assume that +all sub-directories in the path exist and are valid, and that the +actual desired path does not yet exist (Tcl takes care of all of that +for us). + + +[call [cmd vfshandler] [method deletefile] [arg root] [arg relative] [arg actualpath]] + +Delete the given file. + + +[call [cmd vfshandler] [method fileattributes] [arg root] [arg relative] [arg actualpath] [opt [arg index]] [opt [arg value]]] + +The command has to return a list containing the names of all +acceptable attributes, if neither [arg index] nor [arg value] were +specified. + +[nl] + +The command has to return the value of the [arg index]'th attribute if +the [arg index] is specified, but not the [arg value]. The attributes +are counted in the same order as their names appear in the list +returned by a call where neither [arg index] nor [arg value] were +specified. The first attribute is has the index [const 0]. + +[nl] + +The command has to set the value of the [arg index]'th attribute to +[arg value] if both [arg index] and [arg value] were specified for the +call. + + +[call [cmd vfshandler] [method matchindirectory] [arg root] [arg relative] [arg actualpath] [arg pattern] [arg types]] + +Return the list of files or directories in the given path which match +the glob [arg pattern] and are compatible with the specified list of +[arg types]. The specified path is always the name of an existing +directory. + +[nl] + +[emph 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. + +[nl] + +The commands [cmd vfs::matchDirectories] and [cmd vfs::matchFiles] +(see section [sectref {HANDLER ENVIRONMENT}]) can aid the +implementation greatly in this task. + + +[call [cmd vfshandler] [method open] [arg root] [arg relative] [arg actualpath] [arg mode] [arg permissions]] + +Either returns a list describing the sucessfully opened file, or +throws an error describing how the operation failed. + +[nl] + +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 [method open]. + +[nl] + +If present the specified callback will be evaluated by the generic +filesystem layer just before the channel whose handle was returned as +the first element of the list is closed. Additionally all available +data will have been flushed into it. 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 crucical to the cleanup of any resouces +associated with an opened file, but also for the ability to implement +a filesystem which can be written to. + +[nl] + +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 [cmd bgerror]. + +However if, through a call of the subcommand [method 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. + + +[list_begin definitions] + +[lst_item [arg mode]] +can be any of [const r], [const w], [const a], [const w+], or [const a+]. + +[lst_item [arg permissions]] +determines the native mode the openend file is created with. Relevant +only of the open [arg mode] actually requests the creation of a +non-existing file, i.e. is not [const r]. + +[list_end] +[nl] + +[call [cmd vfshandler] [method removedirectory] [arg root] [arg relative] [arg actualpath] [arg recursive]] + +Delete the given directory. Argument [arg recursive] is a boolean. If +the specified value is [const true] then even if the directory is +non-empty, an attempt has to be made to recursively delete it and its +contents. If the spcified value is [const false] and the directory is +non-empty, a posix error ([const ENOTEMPTY]) has to be thrown. + + +[call [cmd vfshandler] [method stat] [arg root] [arg relative] [arg actualpath]] + +The result has to be a list of keys and values, in a format acceptable +to the builtin command [cmd {array set}]. It describes the contents of +a stat structure. The order of the keys in the list is not important. + +[nl] + +Given this the subcommand should use something like + +[example {return [list dev 0 type file mtime 1234 ...].}] + +as the last command of its implementation. + +[nl] + +The following keys and their values have to be supplied by the +filesystem: + +[list_begin definitions] +[lst_item [const dev]] + +A long integer number, the device number of the path stat was called for. + +[lst_item [const ino]] + +A long integer number, the inode number of the path stat was called for. + +Each path handled by the filesystem should be uniquely identified by +the combination of device and inode number. Violating this principle +will cause higher-level algorithms which(have to) keep track of device +and inode information to fail in all manners possible. + +[nl] + +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. + +[lst_item [const mode]] + +An integer number, the access mode of the path. It is this mode which +is checked by the subcommand [method access]. + +[lst_item [const nlink]] + +A long integer number, the number of hard links to the specified path. + +[lst_item [const uid]] + +A long integer number, the id of the user owning the virtual path. + +[lst_item [const gid]] + +A long integer number, the id of the user group the virtual path +belongs to. + +[lst_item [const size]] + +A long integer number, the true size of the virtual path, in bytes. + +[lst_item [const atime]] + +A long integer number, the time of the latest access to the path, in +seconds since the epoch. Convertible into a readable date/time by the +command [cmd {clock format}]. + +[lst_item [const mtime]] + +A long integer number, the time of the latest modification of the +path, in seconds since the epoch. Convertible into a readable +date/time by the command [cmd {clock format}]. + +[lst_item [const ctime]] + +A long integer number, the time of the path was created, in seconds +since the epoch. Convertible into a readable date/time by the command +[cmd {clock format}]. + +[lst_item [const type]] + +A string, either [const directory], or [const file], describing the +type of the given path. + +[list_end] +[nl] + +[call [cmd vfshandler] [method utime] [arg root] [arg relative] [arg actualpath] [arg actime] [arg mtime]] + +Set the access and modification times of the given file (these are +read with [method stat]). + +[list_end] + + +[section {HANDLER ENVIRONMENT}] + +The implementation of a filesystem handler can rely on the +existence of the following utility commands: + +[list_begin definitions] +[call [cmd vfs::accessMode] [arg mode]] + +This commands converts an access [arg mode] given as integer into a +string, one of [const F], [const X], [const W], [const XW], [const R], +[const RX], and [const RW]. + + +[call [cmd vfs::matchDirectories] [arg types]] + +Checks if the glob types specification ask for the inclusion of +directories. Returns a boolean result. [const true] is returned if +types does ask for directories, else [const false]. + + +[call [cmd vfs::matchFiles] [arg types]] + +Checks if the glob types specification ask for the inclusion of +files. Returns a boolean result. [const true] is returned if types +does ask for directories, else [const false]. + + +[call [cmd vfs::matchCorrectTypes] [arg types] [arg filelist] [opt [arg inDir]]] + +Returns that subset of the [arg filelist] which are compatible with +the [arg types] given. The elements of [arg filelist] are either +absolute paths, or names of files in the directory [arg indir]. The +latter interpretation is taken if and only if the argument [arg indir] +is specified. + + +[list_end] + +[section {FILESYSTEM DEBUGGING}] + +To debug a problem in the implementation of a filesystem use code as +shown below. This registers the command [cmd report] as the error +handler for the filesystem, which in turn prints out the error stack +provided by tcl. + +[para] +[example {vfs::filesystem internalerror report + +proc report {} { + puts stderr $::errorInfo +}}] + +[see_also vfs vfs-filesystems] +[keywords vfs filesystem file] +[manpage_end] + diff --git a/doc/vfs.man b/doc/vfs.man new file mode 100644 index 0000000..09f2205 --- /dev/null +++ b/doc/vfs.man @@ -0,0 +1,203 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin vfs n 1.0] +[copyright {2001-2003 Vince Darley }] +[copyright {2003 Andreas Kupries }] +[moddesc {Tcl-level Virtual Filesystems}] +[titledesc {Filesystem management in Tcl}] +[require Tcl 8.4] +[require vfs [opt 1.2]] +[description] + +The package [package vfs] provides commands to query, mount and +unmount virtual filesystems implemented in Tcl. This is further +facilitated through the provison of helper commands in a tcl script +library. See section "HANDLER ENVIRONMENT" of [cmd vfs-fsapi] for +more information. + +[para] + +Once a virtual filesystem is in place, the standard Tcl commands, like +[cmd file], [cmd glob], [cmd cd], [cmd pwd], [cmd open], including all +their C APIs in the Tcl library (e.g. + +[fun Tcl_FSOpenFileChannel], [fun Tcl_FSMatchInDirectory], +...), can be used within the filesystem (and indeed, properly written +extensions such as [package Tk] which may open or read files will also +transparently access the virtual filesystem). + +[para] + +Because all of Tcl's filesystem activity passes through a single +layer, every operation can be intercepted. This package does just +that. + +This is also quite different from simply overloading the [cmd file] +command in Tcl. We are actually providing replacements for C commands +like [syscmd access], [syscmd stat], etc. + +By implementing a small number of low-level commands we ensure that +all commands at higher levels will function irrespective of what is +going on inside the filesystem layer. + +[para] + +Tcl's filesystem hooks operate on a per-process basis. This means +every Tcl interpreter in the same process/application will see the +same filesystem, including any virtual filesystems. + +[para] + +To access this package use the command [cmd {package require vfs}]. + +This automatically registers the vfs hooks into Tcl's filesystem and +provides the command [cmd vfs::filesystem]. The latter allows the +registration of actual virtual filesystems. More in the upcoming +section [sectref API]. + +The hooks will not be removed until Tcl exits. If desired, control +over this could be exposed to Tcl in the future. + +By and in itself the command above will have no further effect. Only +after filesystem implementations have been registered and filesystems +using them been mounted filesystem commands will actually be +intercepted, and handled by the Tcl code of the mounted virtual +filesystem. + + +[section API] + +[list_begin definitions] + +[call [cmd vfs::filesystem] [method mount] [opt [option -volume]] [arg path] [arg command]] + +[term Mount]s a virtual filesystem at [arg path], making it +useable. After completion of the call any access to a subdirectory of +[arg path] will be handled by that filesystem. The filesystem is +represented here by the [arg command] prefix which will be executed +whenever an operation on a file or directory within [arg path] has to +be performed. + +[nl] + +Whether the [arg command] is implemented in C or Tcl is of no +relevance as long as it adheres to the API specified in + +[cmd vfs-fsapi] and is present in the interpreter where the mount +operation is executed. + +[nl] + +If the option [option -volume] is specified the new mount point is +also registered with Tcl as a new volume and will therefore from then +on appear in the output of the command [cmd {file volumes}]. This is +useful (and required for reasonable operation) for mounts like + +[const ftp://]. It should not be used for paths mounted inside the +native filesystem. + +[nl] + +The new filesystem mounts will be observed immediately in all +interpreters in the current process. If the interpreter is later +deleted, all mounts which are intercepted by it will be automatically +removed (and will therefore affect the view of the filesystem seen by +all interpreters). + + +[call [cmd vfs::filesystem] [method unmount] [arg path]] + +This unmounts the virtual filesystem which was mounted at +[arg path]. An error is thrown if no filesystem was mounted there. + +After the completion of the operation the filesystem is not visible +anymore, and any previous filesystem accessible through this path +becomes accessible again. + + +[call [cmd vfs::filesystem] [method info] [opt [arg path]]] + +A list of all filesystems mounted in all interpreters is returned, if +no [arg path] argument was specified. + +Else the filesystem responsible for that [arg path] is examined and +the command prefix used to handle all filesystem operations returned. + +An error is thrown if no filesystem is mounted for that [arg path]. + +[nl] + +There is currently no facility for examining in which interpreter each +command will be evaluated. + + +[call [cmd vfs::filesystem] [method fullynormalize] [arg path]] + +Performs a full expansion of [arg path], (as per [cmd {file +normalize}]). This includes the following of any links in the last +element of [arg path]. + + +[call [cmd vfs::filesystem] [method posixerror] [arg int]] + +This command can be called by filesystem implementations during the +execution of a filesystem operation to signal the posix error code of +a failure. See also [syscmd vfs-fsapi]. + + +[call [cmd vfs::filesystem] [method internalerror] [arg command]] + +When used the specified [arg command] is registerd as the command to +trap and report any internal errors thrown by filesystem +implementations. + +[list_end] + +[section LIMITATIONS] + +The code of the package [package vfs] has only a few limitations. + +[para] + +[list_begin enum] + +[enum] + +One subtlety one has to be aware of is that mixing case-(in)sensitive +filesystems and application code may yield unexpected results. + +[nl] + +For example mounting a case-sensitive virtual filesystem into a +case-insensitive system (like the standard Windows or MacOS +filesystems) and then using this with code relying on +case-insensitivity problems will appear when accessing the virtual +filesystem. + +[nl] + +Note that application code relying on case-insensitivity will not +under Unix either, i.e. is inherently non-portable, and should be +fixed. + + +[enum] + +The C-API's for [method link] and [method lstat] are currently not +exposed to the Tcl level. This may be done in the future to allow +virtual filesystems implemented in Tcl to support the reading and +writing of links. + +[enum] + +The public C-API filesystem function [fun Tcl_FSMatchInDirectory] is +given a variety of type information in a [term Tcl_GlobTypeData] +structure. Currently only the [term type] field of said strcuture is +exposed to the tcl-level. Fields like [term permissions] and MacOS +[term type/creator] are ignored. + +[list_end] + + +[see_also vfs-filesystems vfs-fsapi] +[keywords vfs filesystem file] +[manpage_end] -- 2.23.0