ADC Home > Reference Library > Reference > Mac OS X > Mac OS X Man Pages

 

This document is a Mac OS X manual page. Manual pages are a command-line technology for providing documentation. You can view these manual pages locally using the man(1) command. These manual pages come from many different sources, and thus, have a variety of writing styles.

For more information about the manual page format, see the manual page for manpages(5).



vfs(n)                                  Tcl-only Virtual File Systems                                 vfs(n)



NAME
       ::vfs - Commands and Procedures to create virtual filesystems

SYNOPSIS
       package require Tcl 8.4

       package require vfs ?1.2.1?

       vfs::filesystem info

       vfs::filesystem mount

       vfs::filesystem unmount

       vfs::accessMode mode

       vfs::matchDirectories types

       vfs::matchFiles types

       vfs::matchCorrectTypes types filelist ?inDir?


DESCRIPTION
       The  ::vfs package provides commands to query, mount and unmount virtual filesystems, and provides as
       Tcl libraries some facilities for helping the writing of new virtual filesystems in Tcl.  Once a vir-tual virtual
       tual filesystem is in place, the standard Tcl file, glob, cd, pwd, open commands, including all their
       C APIs in the Tcl library  (e.g.  Tcl_FSOpenFileChannel,  Tcl_FSMatchInDirectory,...),  can  be  used
       within  the  filesystem  (and  indeed,  properly written extensions such as Tk which may open or read
       files will also transparently access the virtual filesystem).   Because  all  of  Tcl's  FS  activity
       passes  through a single layer, it can all be intercepted.  This package does just that.  Notice that
       this is quite different to overloading the file command  in  Tcl.   We  are  actually  providing  vfs
       replacements  for  C  commands like access, stat.  By implementing just a handful of commands at this
       low level, we ensure that all commands at higher levels function irrespective of  what  is  going  on
       inside the FS layer.

       Tcl's  filesystem hooks operate on a per-process basis.  This means every Tcl interpreter in the same
       process/application sees the same filesystem, including any virtual filesystems.

       The package require vfs command should be used to access this library.   It  automatically  registers
       the  vfs hooks into Tcl's filesystem, and these will not be removed until Tcl exits (if desired, con-trol control
       trol over this could be exposed to Tcl in the future).  However, the vfs package will at  that  stage
       not  have  any new filesystems mounted, so it will have little effect.  Note that package require vfs
       has two effects.  First of all, when it is issued in any Tcl interpreter it will ensure the vfs hooks
       have  been  registered with Tcl's core just once (and if any of those interpreters are later deleted,
       the vfs hooks will still remain registered - they remain until Tcl exits).  The second effect  is  to
       provide the command vfs::filesystem which allows the interpreter to intercept filesystem commands and
       handle them with Tcl code in that interpreter.

       There are three somewhat unsupported subcommands of vfs::filesystem, fullynormalize path,  posixerror
       int,  internalerror  ?script?,  which  are used to normalize a path (including any final symlink), to
       register a posix error code with a Tcl error, and to trap/report internal errors in tclvfs  implemen-tations implementations
       tations respectively.

       vfs::filesystem mount ?-volume? path command
              To  use  a  virtual  filesystem, it must be 'mounted'.  Mounting involves declaring to the vfs
              package that any subdirectories of a given path in the filesystem should  be  handled  by  the
              given  command  which  should  be  a  Tcl command or procedure in the interpreter in which the
              vfs::filesystem is executed.  If the ?-volume?  flag is given, the given mount point  is  also
              registered  with  Tcl  as  a  new volume (like a new drive which will appear in file volumes).
              This is useful (and required for reasonable operation) for  mounts  like  ftp://   For  paths
              mounted  inside  the  native filesystem, it should of course not be given.  The new filesystem
              mounts will be observed immediately in all interpreters in the current process.  If the inter-
              preter  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).

       vfs::filesystem unmount path
              This unmounts the virtual filesystem which was mounted at path (hence removing it  from  Tcl's
              filesystem), or throws an error if no filesystem was mounted there.

       vfs::filesystem info ?path?
              If  no  arguments  are  given,  this  returns a list of all filesystems mounted (in all inter-
              preters).  If a path argument is given, then the command to be used for that path is returned,
              or  an error is thrown if no vfs is mounted for that path.  There is currently no facility for
              examining in which interpreter each command will be evaluated.

       vfs::filesystem fullynormalize path
              Performs a full expansion of path, (as per 'file  normalize'),  but  including  following  any
              links in the last element of path.


IMPLEMENTING A TCL ONLY VFS
       The vfs package will intercept every filesystem operation which falls within a given mount point, and
       pass the operation on to the mount point's command in the interpreter which registered it. In general
       this  occurs by the C equivalent of an evaluation like this: eval $command [list $subcmd $root $rela-
       tive $actualpath] $args.

       Here subcmd may be  any  of  the  following:  access,  createdirectory,  deletefile,  fileattributes,
       matchindirectory, open, removedirectory, stat, utime. If command takes appropriate action for each of
       these cases, a complete, perfect virtual filesystem will be achieved, indistinguishable to  Tcl  from
       the native filesystem.  (CAVEATS: right now I don't expose to Tcl all the permission-related flags of
       'glob').

       The remaining arguments specify a file path on which to operate  (all  commands  operate  on  one  of
       these), and any additional arguments which may be required to carry out the action.  The file path is
       specified by three arguments: root is the part of the path which lies outside this filesystem's mount
       point, relative is the part of the path which lies inside this filesytem, and actualpath is the orig-
       inal (unnormalized) name of the path which was used in the current command wherever it originated (in
       Tcl  or  C).   For  example,  if  C:/foo/bar/mount.zip/xxx/yyy  is  a  path in your filesystem, where
       mount.zip is a zip archive which has been mounted (on top of itself) and contains  xxx/yyy,  and  the
       current  working  directory  is  inside  xxx,  and  we  evaluate a command like file exists yyy, then
       rootwill be C:/foo/bar/mount.zip, relative will be xxx/yyy, and actualpath will be yyy. The file sep-
       arator between the root and relative is omitted.

       Note  that  most filesystem operations will only require the relative argument to work correctly, but
       the other arguments are actually required for correct operation of some subcommands.

       Almost all of these commands should either return correctly (i.e. with  a  TCL_OK  result  at  the  C
       level)  or they should use vfs::filesystem posixerror to signal the appropriate posix error code.  If
       a Tcl error is thrown, that should be considered a bug, but it will  be  interpreted  as  an  unknown
       posix  error  in  the  filesystem  call.  The exceptions to these rules are those filesystem commands
       which are able to specify a Tcl  error  message  directly:  open  (when  an  interpreter  is  given),
       matchindirectory  and  fileattributes  (for  a  set or get operation only).  These three commands are
       allowed to throw any Tcl error message which will be passed along to the caller, or they may throw  a
       posix error which will be handled appropriately.

       The  actual  commands  are  as follows (where r-r-a represents the standard argument triplet of root,
       relative and actualpath):

       command access r-r-a mode
              Return TCL_OK or throw a posix error depending on whether the given access mode (which  is  an
              integer) is compatible with the file.

       command createdirectory r-r-a
              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).

       command deletefile r-r-a
              Delete the given file.

       command fileattributes r-r-a ?index? ?value?
              If neither index nor value is given, then return a list of all acceptable attribute names.  If
              index is given, but no value, then retrieve the value of the index'th attribute  (counting  in
              order  over  the  list  returned when no argument is given) for the given file.  If a value is
              also given then set the index'th attribute of the given file to that value.

       command matchindirectory r-r-a pattern types
              Return the list of files or directories in the given path (which is  always  the  name  of  an
              existing  directory),  which match the pattern and are compatible with the types given.  It is
              very important that the command correctly handle types  requests  for  directories  only  (and
              files  only),  because  to  handle  any kind of recursive globbing, Tcl will actually generate
              requests for directory-only matches from the filesystem.  See vfs::matchDirectories below  for
              help.

       command open r-r-a mode permissions
              For  this  command, mode is any of "r", "w", "a", "w+", "a+".  If the open involves creating a
              file, then permissions dictates what modes to create it with.  If the open operation  was  not
              successful,  an  error  should  be  thrown.   If the open operation is successful, the command
              should return a list of either one or two items.  The first item (which is obligatory) is  the
              name  of  the channel which has been created.  The second item, if given, is a Tcl-callback to
              be used when the channel is closed, so that the vfs can clean up as appropriate.   This  call-
              back  will  be  evaluated  by  Tcl  just before the channel is closed.  The channel will still
              exist, and all available data will have been flushed into it.  The callback can, for  example,
              seek  to  the  beginning  of  the channel, read its contents and store that contents elsewhere
              (e.g. compressed or on a remote ftp site, etc).  The return code or any errors returned by the
              callback are ignored (if the callback wishes to signal an error, it must do so asycnhronously,
              with bgerror, for example), unless the 'internalerror' script has been  specified,  when  they
              are passed to that script for further action.

       command removedirectory r-r-a recursive
              Delete the given directory.  recursive is either 0 or 1. If it is 1 then even if the directory
              is non-empty, an attempt should be made to recursively delete it and its contents.  If it is 0
              and the directory is non-empty, a posix error (EEXIST) should be thrown.

       command stat r-r-a
              Return  a list of even length containing field-name and value pairs for the contents of a stat
              structure.  The order is not important.  The option names are dev  (long),  ino  (long),  mode
              (int),  nlink  (long),  uid (long), gid (long), size (long), atime (long), mtime (long), ctime
              (long), type (string which is either "directory" or "file"), where the type of  each  argument
              is  given in brackets.  The procedure should therefore return with something like return [list
              dev 0 type file mtime 1234 ...].

       command utime r-r-a actime mtime
              Set the access and modification times of the given file (these are read with 'stat').


VFS HELPERS
       The vfslib provides a number of Tcl procedures which can help with writing command procedures to han-
       dle the above possibilities.  These are:

       vfs::accessMode mode
              converts an integer access mode to a somewhat more preferable string, any of F X W XW R RX RW.

       vfs::matchDirectories types
              Does types want directories included?

       vfs::matchFiles types
              Does types want files included?

       vfs::matchCorrectTypes types filelist ?inDir?
              Returns that subset of the filelist (which are either absolute paths  or  names  of  files  in
              inDir) which are compatible with the types given.


VFS DEBUGGING
       Use  something  like  this  to  debug  problems in your implementation: vfs::filesystem internalerror
       report ; proc report {} { puts stderr $::errorInfo }


LIMITATIONS
       There are very few limitations to the vfs code.  One subtlety that you may encounter is if you  mount
       a  case-sensitive  virtual  filesystem  into  a case-insensitive system (e.g. the standard Windows or
       MacOS fs) and your code relies on case-insensitivity, then it will not run properly  in  the  virtual
       filesystem.   Of  course if your code relies on case-insensitivity, it wouldn't run under Tcl on Unix
       either, so the best solution is to fix your code!

       We may add link and lstat commands in the future to allow virtual filesystems to support reading  and
       writing links - this is supported by the C API, but has simply not been exposed to Tcl in this exten-
       sion, yet.

       The Tcl 'Tcl_FSMatchInDirectory' function takes a variety of type information in  a  Tcl_GlobTypeData
       structure.   We  currently only expose the 'type' field from that structure (so the 'permissions' and
       MacOS type/creator fields are ignored).

KEYWORDS
       vfs, filesystem, file





Vfs                                                 1.2.1                                             vfs(n)

Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.