1Filesystem(3)               Tcl Library Procedures               Filesystem(3)
2
3
4
5______________________________________________________________________________
6

NAME

8       Tcl_FSRegister,   Tcl_FSUnregister,   Tcl_FSData,  Tcl_FSMountsChanged,
9       Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile,  Tcl_FS‐
10       CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐
11       rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile,  Tcl_FSE‐
12       valFileEx,  Tcl_FSLoadFile,  Tcl_FSUnloadFile,  Tcl_FSMatchInDirectory,
13       Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐
14       trsSet,  Tcl_FSFileAttrStrings,  Tcl_FSStat,  Tcl_FSAccess, Tcl_FSOpen‐
15       FileChannel,    Tcl_FSGetCwd,     Tcl_FSChdir,     Tcl_FSPathSeparator,
16       Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐
17       Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType,  Tcl_FSGetInternalRep,
18       Tcl_FSGetTranslatedPath,   Tcl_FSGetTranslatedStringPath,  Tcl_FSNewNa‐
19       tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐
20       FromStat,        Tcl_GetBlockSizeFromStat,       Tcl_GetBlocksFromStat,
21       Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat,  Tcl_GetFSDevice‐
22       FromStat,        Tcl_GetFSInodeFromStat,        Tcl_GetGroupIdFromStat,
23       Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐
24       FromStat,  Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf
25       - procedures to interact with any filesystem
26

SYNOPSIS

28       #include <tcl.h>
29
30       int
31       Tcl_FSRegister(clientData, fsPtr)
32
33       int
34       Tcl_FSUnregister(fsPtr)
35
36       ClientData
37       Tcl_FSData(fsPtr)
38
39       void
40       Tcl_FSMountsChanged(fsPtr)
41
42       const Tcl_Filesystem *
43       Tcl_FSGetFileSystemForPath(pathPtr)
44
45       Tcl_PathType
46       Tcl_FSGetPathType(pathPtr)
47
48       int
49       Tcl_FSCopyFile(srcPathPtr, destPathPtr)
50
51       int
52       Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr)
53
54       int
55       Tcl_FSCreateDirectory(pathPtr)
56
57       int
58       Tcl_FSDeleteFile(pathPtr)
59
60       int
61       Tcl_FSRemoveDirectory(pathPtr, int recursive, errorPtr)
62
63       int
64       Tcl_FSRenameFile(srcPathPtr, destPathPtr)
65
66       Tcl_Obj *
67       Tcl_FSListVolumes(void)
68
69       int
70       Tcl_FSEvalFileEx(interp, pathPtr, encodingName)
71
72       int
73       Tcl_FSEvalFile(interp, pathPtr)
74
75       int
76       Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
77                      loadHandlePtr, unloadProcPtr)
78
79       int                                                                     │
80       Tcl_FSUnloadFile(interp, loadHandle)                                    │
81
82       int
83       Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
84
85       Tcl_Obj *
86       Tcl_FSLink(linkNamePtr, toPtr, linkAction)
87
88       int
89       Tcl_FSLstat(pathPtr, statPtr)
90
91       int
92       Tcl_FSUtime(pathPtr, tval)
93
94       int
95       Tcl_FSFileAttrsGet(interp, int index, pathPtr, objPtrRef)
96
97       int
98       Tcl_FSFileAttrsSet(interp, int index, pathPtr, Tcl_Obj *objPtr)
99
100       const char *const *
101       Tcl_FSFileAttrStrings(pathPtr, objPtrRef)
102
103       int
104       Tcl_FSStat(pathPtr, statPtr)
105
106       int
107       Tcl_FSAccess(pathPtr, mode)
108
109       Tcl_Channel
110       Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions)
111
112       Tcl_Obj *
113       Tcl_FSGetCwd(interp)
114
115       int
116       Tcl_FSChdir(pathPtr)
117
118       Tcl_Obj *
119       Tcl_FSPathSeparator(pathPtr)
120
121       Tcl_Obj *
122       Tcl_FSJoinPath(listObj, elements)
123
124       Tcl_Obj *
125       Tcl_FSSplitPath(pathPtr, lenPtr)
126
127       int
128       Tcl_FSEqualPaths(firstPtr, secondPtr)
129
130       Tcl_Obj *
131       Tcl_FSGetNormalizedPath(interp, pathPtr)
132
133       Tcl_Obj *
134       Tcl_FSJoinToPath(basePtr, objc, objv)
135
136       int
137       Tcl_FSConvertToPathType(interp, pathPtr)
138
139       ClientData
140       Tcl_FSGetInternalRep(pathPtr, fsPtr)
141
142       Tcl_Obj *
143       Tcl_FSGetTranslatedPath(interp, pathPtr)
144
145       const char *
146       Tcl_FSGetTranslatedStringPath(interp, pathPtr)
147
148       Tcl_Obj *
149       Tcl_FSNewNativePath(fsPtr, clientData)
150
151       const void *
152       Tcl_FSGetNativePath(pathPtr)
153
154       Tcl_Obj *
155       Tcl_FSFileSystemInfo(pathPtr)
156
157       Tcl_StatBuf *
158       Tcl_AllocStatBuf()
159
160       Tcl_WideInt                                                             │
161       Tcl_GetAccessTimeFromStat(statPtr)                                      │
162
163       unsigned                                                                │
164       Tcl_GetBlockSizeFromStat(statPtr)                                       │
165
166       Tcl_WideUInt                                                            │
167       Tcl_GetBlocksFromStat(statPtr)                                          │
168
169       Tcl_WideInt                                                             │
170       Tcl_GetChangeTimeFromStat(statPtr)                                      │
171
172       int                                                                     │
173       Tcl_GetDeviceTypeFromStat(statPtr)                                      │
174
175       unsigned                                                                │
176       Tcl_GetFSDeviceFromStat(statPtr)                                        │
177
178       unsigned                                                                │
179       Tcl_GetFSInodeFromStat(statPtr)                                         │
180
181       int                                                                     │
182       Tcl_GetGroupIdFromStat(statPtr)                                         │
183
184       int                                                                     │
185       Tcl_GetLinkCountFromStat(statPtr)                                       │
186
187       unsigned                                                                │
188       Tcl_GetModeFromStat(statPtr)                                            │
189
190       Tcl_WideInt                                                             │
191       Tcl_GetModificationTimeFromStat(statPtr)                                │
192
193       Tcl_WideUInt                                                            │
194       Tcl_GetSizeFromStat(statPtr)                                            │
195
196       int                                                                     │
197       Tcl_GetUserIdFromStat(statPtr)                                          │
198

ARGUMENTS

200       const Tcl_Filesystem *fsPtr (in)            Points to a structure  con‐
201                                                   taining  the  addresses  of
202                                                   procedures  that   can   be
203                                                   called to perform the vari‐
204                                                   ous filesystem operations.
205
206       Tcl_Obj *pathPtr (in)                       The  path  represented   by
207                                                   this  value is used for the
208                                                   operation in  question.  If
209                                                   the  value does not already
210                                                   have an internal path  rep‐
211                                                   resentation,   it  will  be
212                                                   converted to have one.
213
214       Tcl_Obj *srcPathPtr (in)                    As for  pathPtr,  but  used
215                                                   for  the  source file for a
216                                                   copy or rename operation.
217
218       Tcl_Obj *destPathPtr (in)                   As for  pathPtr,  but  used
219                                                   for  the  destination file‐
220                                                   name for a copy  or  rename
221                                                   operation.
222
223       const char *encodingName (in)               The  encoding  of  the data
224                                                   stored in the file  identi‐
225                                                   fied  by  pathPtr and to be
226                                                   evaluated.
227
228       const char *pattern (in)                    Only files  or  directories
229                                                   matching  this pattern will
230                                                   be returned.
231
232       Tcl_GlobTypeData *types (in)                Only files  or  directories
233                                                   matching  the type descrip‐
234                                                   tions  contained  in   this
235                                                   structure will be returned.
236                                                   This parameter may be NULL.
237
238       Tcl_Interp *interp (in)                     Interpreter to  use  either
239                                                   for results, evaluation, or
240                                                   reporting error messages.
241
242       ClientData clientData (in)                  The native  description  of
243                                                   the path value to create.
244
245       Tcl_Obj *firstPtr (in)                      The  first of two path val‐
246                                                   ues to compare.  The  value
247                                                   may  be  converted  to path
248                                                   type.
249
250       Tcl_Obj *secondPtr (in)                     The second of two path val‐
251                                                   ues  to  compare. The value
252                                                   may be  converted  to  path
253                                                   type.
254
255       Tcl_Obj *listObj (in)                       The  list  of path elements
256                                                   to operate on with  a  join
257                                                   operation.
258
259       int elements (in)                           If non-negative, the number
260                                                   of elements in the  listObj
261                                                   which  should be joined to‐
262                                                   gether. If  negative,  then
263                                                   all elements are joined.
264
265       Tcl_Obj **errorPtr (out)                    In  the  case  of an error,
266                                                   filled with  a  value  con‐
267                                                   taining  the  name  of  the
268                                                   file which caused an  error
269                                                   in  the various copy/rename
270                                                   operations.
271
272       Tcl_Obj **objPtrRef (out)                   Filled with  a  value  con‐
273                                                   taining  the  result of the
274                                                   operation.
275
276       Tcl_Obj *resultPtr (out)                    Pre-allocated   value    in
277                                                   which   to   store   (using
278                                                   Tcl_ListObjAppendElement)
279                                                   the list of files or direc‐
280                                                   tories which  are  success‐
281                                                   fully matched.
282
283       int mode (in)                               Mask  consisting  of one or
284                                                   more of  R_OK,  W_OK,  X_OK
285                                                   and  F_OK.  R_OK,  W_OK and
286                                                   X_OK    request    checking
287                                                   whether the file exists and
288                                                   has  read, write and   exe‐
289                                                   cute   permissions, respec‐
290                                                   tively. F_OK just  requests
291                                                   checking  for the existence
292                                                   of the file.
293
294       Tcl_StatBuf *statPtr (out)                  The structure that contains
295                                                   the  result  of  a  stat or
296                                                   lstat operation.
297
298       const char *sym1 (in)                       Name of a procedure to look
299                                                   up in the file's symbol ta‐
300                                                   ble
301
302       const char *sym2 (in)                       Name of a procedure to look
303                                                   up in the file's symbol ta‐
304                                                   ble
305
306       Tcl_PackageInitProc **proc1Ptr (out)        Filled with the init  func‐
307                                                   tion for this code.
308
309       Tcl_PackageInitProc **proc2Ptr (out)        Filled  with  the safe-init
310                                                   function for this code.
311
312       ClientData *clientDataPtr (out)             Filled with the  clientData
313                                                   value   to   pass  to  this
314                                                   code's unload function when
315                                                   it is called.
316
317       Tcl_LoadHandle *loadHandlePtr (out)         Filled with an abstract to‐
318                                                   ken representing the loaded
319                                                   file.
320
321       Tcl_FSUnloadFileProc **unloadProcPtr (out)  Filled with the function to
322                                                   use to unload this piece of
323                                                   code.
324
325       Tcl_LoadHandle loadHandle (in)              Handle  to  the  loaded li‐
326                                                   brary to be unloaded.
327
328       utimbuf *tval (in)                          The access and modification
329                                                   times in this structure are
330                                                   read and used to set  those
331                                                   values for a given file.
332
333       const char *modeString (in)                 Specifies  how  the file is
334                                                   to be  accessed.  May  have
335                                                   any  of  the values allowed
336                                                   for the  mode  argument  to
337                                                   the Tcl open command.
338
339       int permissions (in)                        POSIX-style      permission
340                                                   flags such as  0644.  If  a
341                                                   new  file is created, these
342                                                   permissions will be set  on
343                                                   the created file.
344
345       int *lenPtr (out)                           If  non-NULL,  filled  with
346                                                   the number of  elements  in
347                                                   the split path.
348
349       Tcl_Obj *basePtr (in)                       The  base  path on to which
350                                                   to join the given elements.
351                                                   May be NULL.
352
353       int objc (in)                               The  number  of elements in
354                                                   objv.
355
356       Tcl_Obj *const objv[] (in)                  The elements to join to the
357                                                   given base path.
358
359       Tcl_Obj *linkNamePtr (in)                   The  name of the link to be
360                                                   created or read.
361
362       Tcl_Obj *toPtr (in)                         What   the   link    called
363                                                   linkNamePtr    should    be
364                                                   linked to, or NULL  if  the
365                                                   symbolic  link specified by
366                                                   linkNamePtr is to be read.
367
368       int linkAction (in)                         OR-ed combination of  flags
369                                                   indicating   what  kind  of
370                                                   link  should   be   created
371                                                   (will  be  ignored if toPtr
372                                                   is NULL). Valid bits to set
373                                                   are         TCL_CREATE_SYM‐
374                                                   BOLIC_LINK   and   TCL_CRE‐
375                                                   ATE_HARD_LINK.   When  both
376                                                   flags are set and  the  un‐
377                                                   derlying  filesystem can do
378                                                   either, symbolic links  are
379                                                   preferred.
380______________________________________________________________________________
381

DESCRIPTION

383       There  are  several  reasons  for  calling  the  Tcl_FS  API  functions
384       (e.g. Tcl_FSAccess and Tcl_FSStat) rather  than  calling  system  level
385       functions  like  access and stat directly. First, they will work cross-
386       platform, so an extension which calls them should  work  unmodified  on
387       Unix  and  Windows. Second, the Windows implementation of some of these
388       functions fixes some bugs in the system level calls. Third, these func‐
389       tion  calls  deal  with  any  “Utf to platform-native” path conversions
390       which may be required (and may cache the results  of  such  conversions
391       for  greater  efficiency on subsequent calls). Fourth, and perhaps most
392       importantly, all of these functions  are  “virtual  filesystem  aware”.
393       Any  virtual  filesystem  (VFS  for  short)  which  has been registered
394       (through Tcl_FSRegister) may reroute file access to  alternative  media
395       or  access  methods. This means that all of these functions (and there‐
396       fore the corresponding file, glob, pwd, cd,  open,  etc. Tcl  commands)
397       may  be  operate  on  “files”  which are not native files in the native
398       filesystem. This also means that any Tcl extension which  accesses  the
399       filesystem  (FS  for  short) through this API is automatically “virtual
400       filesystem aware”.  Of course, if  an  extension  accesses  the  native
401       filesystem directly (through platform-specific APIs, for example), then
402       Tcl cannot intercept such calls.
403
404       If appropriate VFSes have been registered, the “files” may, to give two
405       examples,  be remote (e.g. situated on a remote ftp server) or archived
406       (e.g. lying inside a .zip archive). Such registered filesystems provide
407       a lookup table of functions to implement all or some of the functional‐
408       ity listed here. Finally, the Tcl_FSStat and Tcl_FSLstat calls abstract
409       away from what the “struct stat” buffer is actually declared to be, al‐
410       lowing the same code to be used both on systems with and systems  with‐
411       out support for files larger than 2GB in size.
412
413       The  Tcl_FS API is Tcl_Obj-ified and may cache internal representations
414       and other path-related strings (e.g. the  current  working  directory).
415       One side-effect of this is that one must not pass in values with a ref‐
416       erence count of zero to any of these functions. If such calls were han‐
417       dled,  they might result in memory leaks (under some circumstances, the
418       filesystem code may wish to retain a reference to the passed in  value,
419       and  so  one  must not assume that after any of these calls return, the
420       value still has a reference count of zero - it  may  have  been  incre‐
421       mented)  or  in a direct segmentation fault (or other memory access er‐
422       ror) due to the value being freed part way through  the  complex  value
423       manipulation  required  to ensure that the path is fully normalized and
424       absolute for filesystem determination. The practical  lesson  to  learn
425       from this is that
426
427              Tcl_Obj *path = Tcl_NewStringObj(...);
428              Tcl_FSWhatever(path);
429              Tcl_DecrRefCount(path);
430
431       is wrong, and may cause memory errors. The path must have its reference
432       count incremented before passing it in, or decrementing  it.  For  this
433       reason,  values with a reference count of zero are considered not to be
434       valid filesystem paths and calling any Tcl_FS API function with such  a
435       value will result in no action being taken.
436
437   FS API FUNCTIONS
438       Tcl_FSCopyFile  attempts  to  copy  the file given by srcPathPtr to the
439       path name given by destPathPtr. If the two paths given lie in the  same
440       filesystem (according to Tcl_FSGetFileSystemForPath) then that filesys‐
441       tem's “copy file” function is called (if it  is  non-NULL).   Otherwise
442       the  function  returns  -1  and sets the errno global C variable to the
443       “EXDEV” POSIX error code (which signifies a “cross-domain link”).
444
445       Tcl_FSCopyDirectory attempts to copy the directory given by  srcPathPtr
446       to  the  path  name given by destPathPtr. If the two paths given lie in
447       the same filesystem (according to Tcl_FSGetFileSystemForPath) then that
448       filesystem's  “copy file” function is called (if it is non-NULL).  Oth‐
449       erwise the function returns -1 and sets the errno global C variable  to
450       the “EXDEV” POSIX error code (which signifies a “cross-domain link”).
451
452       Tcl_FSCreateDirectory attempts to create the directory given by pathPtr
453       by calling the owning filesystem's “create directory” function.
454
455       Tcl_FSDeleteFile attempts to delete the file given by pathPtr by  call‐
456       ing the owning filesystem's “delete file” function.
457
458       Tcl_FSRemoveDirectory attempts to remove the directory given by pathPtr
459       by calling the owning filesystem's “remove directory” function.
460
461       Tcl_FSRenameFile attempts to rename the file or directory given by src‐
462       PathPtr  to  the path name given by destPathPtr. If the two paths given
463       lie in the same filesystem  (according  to  Tcl_FSGetFileSystemForPath)
464       then  that filesystem's “rename file” function is called (if it is non-
465       NULL). Otherwise the function returns -1 and sets the  errno  global  C
466       variable  to the “EXDEV” POSIX error code (which signifies a “cross-do‐
467       main link”).
468
469       Tcl_FSListVolumes calls each filesystem which has a non-NULL “list vol‐
470       umes”  function  and asks them to return their list of root volumes. It
471       accumulates the return values in a list which is returned to the caller
472       (with a reference count of 0).
473
474       Tcl_FSEvalFileEx  reads  the  file  given by pathPtr using the encoding
475       identified by encodingName and evaluates its contents as a Tcl  script.
476       It  returns  the same information as Tcl_EvalObjEx.  If encodingName is
477       NULL, the system encoding is used for reading the  file  contents.   If
478       the file could not be read then a Tcl error is returned to describe why
479       the file could not be read.  The eofchar for files is  “\32”  (^Z)  for
480       all  platforms.   If  you require a “^Z” in code for string comparison,
481       you can use “\032” or “\u001a”, which will be safely substituted by the
482       Tcl  interpreter  into  “^Z”.   Tcl_FSEvalFile  is a simpler version of
483       Tcl_FSEvalFileEx that always uses the system encoding when reading  the
484       file.
485
486       Tcl_FSLoadFile dynamically loads a binary code file into memory and re‐
487       turns the addresses of two procedures within that file, if they are de‐
488       fined. The appropriate function for the filesystem to which pathPtr be‐
489       longs will be called. If that filesystem does not implement this  func‐
490       tion  (most  virtual filesystems will not, because of OS limitations in
491       dynamically loading binary code), Tcl will attempt to copy the file  to
492       a  temporary  directory and load that temporary file.  Tcl_FSUnloadFile 
493       reverses the operation, asking for the library indicated by  the  load‐
494       Handle  to  be removed from the process. Note that, unlike with the un‐ 
495       load command, this does not give the library any opportunity  to  clean │
496       up.
497
498       Both  the  above functions return a standard Tcl completion code. If an
499       error occurs, an error message is left in the interp's result.
500
501       The token provided via the variable indicated by loadHandlePtr  may  be │
502       used with Tcl_FindSymbol.
503
504       Tcl_FSMatchInDirectory  is used by the globbing code to search a direc‐
505       tory for all files which match a given pattern. The  appropriate  func‐
506       tion for the filesystem to which pathPtr belongs will be called.
507
508       The  return  value is a standard Tcl result indicating whether an error
509       occurred in globbing. Error messages are placed in interp  (unless  in‐
510       terp is NULL, which is allowed), but good results are placed in the re‐
511       sultPtr given.
512
513       Note that the glob code implements recursive  patterns  internally,  so
514       this  function  will  only ever be passed simple patterns, which can be
515       matched using the logic of string match. To handle recursion, Tcl  will
516       call  this  function  frequently  asking only for directories to be re‐
517       turned. A special case of being called with a  NULL  pattern  indicates
518       that the path needs to be checked only for the correct type.
519
520       Tcl_FSLink  replaces the library version of readlink, and extends it to
521       support the  creation  of  links.  The  appropriate  function  for  the
522       filesystem to which linkNamePtr belongs will be called.
523
524       If  the toPtr is NULL, a “read link” action is performed. The result is
525       a Tcl_Obj specifying  the  contents  of  the  symbolic  link  given  by
526       linkNamePtr, or NULL if the link could not be read. The result is owned
527       by the caller, which should call Tcl_DecrRefCount when the result is no
528       longer  needed.  If  the toPtr is not NULL, Tcl should create a link of
529       one of the types passed in in the linkAction flag. This flag is an ORed
530       combination   of   TCL_CREATE_SYMBOLIC_LINK  and  TCL_CREATE_HARD_LINK.
531       Where a choice exists (i.e. more than one flag is passed in),  the  Tcl
532       convention  is  to  prefer  symbolic links. When a link is successfully
533       created, the return value should be toPtr (which is  therefore  already
534       owned by the caller). If unsuccessful, NULL is returned.
535
536       Tcl_FSLstat  fills  the  Tcl_StatBuf structure statPtr with information
537       about the specified file. You do not need any access rights to the file
538       to  get  this information but you need search rights to all directories
539       named in the path leading to the file. The  Tcl_StatBuf  structure  in‐
540       cludes  info  regarding  device, inode (always 0 on Windows), privilege
541       mode, nlink (always 1 on Windows), user id (always 0 on Windows), group
542       id  (always 0 on Windows), rdev (same as device on Windows), size, last
543       access time, last modification time, and  last  metadata  change  time.
544       See PORTABLE STAT RESULT API for a description of how to write portable
545       code to allocate and access the Tcl_StatBuf structure.
546
547       If path exists, Tcl_FSLstat returns 0 and the stat structure is  filled
548       with data. Otherwise, -1 is returned, and no stat info is given.
549
550       Tcl_FSUtime replaces the library version of utime.
551
552       This  returns 0 on success and -1 on error (as per the utime documenta‐
553       tion). If successful, the function will update the “atime” and  “mtime”
554       values of the file given.
555
556       Tcl_FSFileAttrsGet  implements  read  access  for the hookable file at‐
557       tributes subcommand. The appropriate function  for  the  filesystem  to
558       which pathPtr belongs will be called.
559
560       If  the  result  is TCL_OK, then a value was placed in objPtrRef, which
561       will only be temporarily valid (unless Tcl_IncrRefCount is called).
562
563       Tcl_FSFileAttrsSet implements write access for the  hookable  file  at‐
564       tributes  subcommand.  The  appropriate  function for the filesystem to
565       which pathPtr belongs will be called.
566
567       Tcl_FSFileAttrStrings implements part of the hookable  file  attributes
568       subcommand.  The appropriate function for the filesystem to which path‐
569       Ptr belongs will be called.
570
571       The called procedure may either return an array of strings, or may  in‐
572       stead  return  NULL  and place a Tcl list into the given objPtrRef. Tcl
573       will take that list and first increment its reference count before  us‐
574       ing  it.   On  completion of that use, Tcl will decrement its reference
575       count. Hence if the list should be disposed of by  Tcl  when  done,  it
576       should  have  a  reference count of zero, and if the list should not be
577       disposed of, the filesystem should ensure it retains a reference  count
578       to the value.
579
580       Tcl_FSAccess checks whether the process would be allowed to read, write
581       or test for existence of the file (or other  filesystem  object)  whose
582       name  is pathname. If pathname is a symbolic link on Unix, then permis‐
583       sions of the file referred by this symbolic link are tested.
584
585       On success (all requested permissions granted), zero  is  returned.  On
586       error  (at least one bit in mode asked for a permission that is denied,
587       or some other error occurred), -1 is returned.
588
589       Tcl_FSStat fills the Tcl_StatBuf  structure  statPtr  with  information
590       about the specified file. You do not need any access rights to the file
591       to get this information but you need search rights to  all  directories
592       named  in  the  path leading to the file. The Tcl_StatBuf structure in‐
593       cludes info regarding device, inode (always 0  on  Windows),  privilege
594       mode, nlink (always 1 on Windows), user id (always 0 on Windows), group
595       id (always 0 on Windows), rdev (same as device on Windows), size,  last
596       access  time,  last  modification  time, and last metadata change time.
597       See PORTABLE STAT RESULT API for a description of how to write portable
598       code to allocate and access the Tcl_StatBuf structure.
599
600       If  path  exists, Tcl_FSStat returns 0 and the stat structure is filled
601       with data. Otherwise, -1 is returned, and no stat info is given.
602
603       Tcl_FSOpenFileChannel opens a file specified by pathPtr and  returns  a
604       channel  handle  that  can  be  used to perform input and output on the
605       file. This API is modeled after the fopen procedure of the  Unix  stan‐
606       dard  I/O  library.  The syntax and meaning of all arguments is similar
607       to those given in the Tcl open command when opening a file.  If an  er‐
608       ror  occurs  while  opening  the channel, Tcl_FSOpenFileChannel returns
609       NULL and records  a  POSIX  error  code  that  can  be  retrieved  with
610       Tcl_GetErrno.   In addition, if interp is non-NULL, Tcl_FSOpenFileChan‐
611       nel leaves an error message in interp's result after any error.
612
613       The newly created channel is not  registered  in  the  supplied  inter‐
614       preter;  to  register it, use Tcl_RegisterChannel.  If one of the stan‐
615       dard channels, stdin, stdout or stderr was previously closed,  the  act
616       of  creating  the  new channel also assigns it as a replacement for the
617       standard channel.
618
619       Tcl_FSGetCwd replaces the library version of getcwd.
620
621       It returns the Tcl library's current working  directory.  This  may  be
622       different  to  the  native  platform's working directory, which happens
623       when the current working directory is not in the native filesystem.
624
625       The result is a pointer to a Tcl_Obj specifying the current  directory,
626       or  NULL  if  the current directory could not be determined. If NULL is
627       returned, an error message is left in the interp's result.
628
629       The result already has its reference count incremented for the  caller.
630       When  it  is  no  longer  needed, that reference count should be decre‐
631       mented. This is needed for thread-safety purposes,  to  allow  multiple
632       threads  to  access  this and related functions, while ensuring the re‐
633       sults are always valid.
634
635       Tcl_FSChdir replaces the library version of chdir. The path is  normal‐
636       ized  and  then  passed  to  the  filesystem  which  claims it. If that
637       filesystem does not implement this function, Tcl  will  fallback  to  a
638       combination  of  stat  and access to check whether the directory exists
639       and has appropriate permissions.
640
641       For results, see chdir documentation. If successful, we keep  a  record
642       of  the  successful  path in cwdPathPtr for subsequent calls to Tcl_FS‐
643       GetCwd.
644
645       Tcl_FSPathSeparator returns the separator character to be used for most
646       specific  element  of the path specified by pathPtr (i.e. the last part
647       of the path).
648
649       The separator is returned as a Tcl_Obj containing a string of length 1.
650       If the path is invalid, NULL is returned.
651
652       Tcl_FSJoinPath  takes  the  given  Tcl_Obj,  which must be a valid list
653       (which is allowed to have a reference count of zero), and  returns  the
654       path  value  given  by considering the first elements elements as valid
655       path segments (each path segment may be a complete path, a partial path
656       or  just a single possible directory or file name). If any path segment
657       is actually an absolute path, then all prior  path  segments  are  dis‐
658       carded.  If elements is less than 0, we use the entire list.
659
660       It  is  possible  that the returned value is actually an element of the
661       given list, so the caller should be careful to increment the  reference
662       count of the result before freeing the list.
663
664       The  returned  value,  typically with a reference count of zero (but it
665       could be shared under some conditions), contains the joined  path.  The
666       caller must add a reference count to the value before using it. In par‐
667       ticular, the returned value could be an element of the given  list,  so
668       freeing the list might free the value prematurely if no reference count
669       has been taken.  If the number of elements is zero, then  the  returned
670       value will be an empty-string Tcl_Obj.
671
672       Tcl_FSSplitPath  takes the given Tcl_Obj, which should be a valid path,
673       and returns a Tcl list value containing each segment of that path as an
674       element.   It  returns  a list value with a reference count of zero. If
675       the passed in lenPtr is non-NULL, the variable it points to will be up‐
676       dated to contain the number of elements in the returned list.
677
678       Tcl_FSEqualPaths  tests  whether the two paths given represent the same
679       filesystem object.  It returns 1 if the paths are equal, and 0 if  they
680       are different. If either path is NULL, 0 is always returned.
681
682       Tcl_FSGetNormalizedPath  this  important  function  attempts to extract
683       from the given Tcl_Obj a unique normalized path  representation,  whose
684       string value can be used as a unique identifier for the file.
685
686       It returns the normalized path value, owned by Tcl, or NULL if the path
687       was invalid or could otherwise not be successfully converted.   Extrac‐
688       tion  of  absolute,  normalized  paths  is  very efficient (because the
689       filesystem operates on these representations internally), although  the
690       result  when the filesystem contains numerous symbolic links may not be
691       the most user-friendly version of a path. The return value is owned  by
692       Tcl and has a lifetime equivalent to that of the pathPtr passed in (un‐
693       less that is a relative path, in which case the normalized  path  value
694       may  be  freed any time the cwd changes) - the caller can of course in‐
695       crement the reference count if it wishes to maintain a copy for longer.
696
697       Tcl_FSJoinToPath takes the given value, which should usually be a valid
698       path or NULL, and joins onto it the array of paths segments given.
699
700       Returns  a  value, typically with reference count of zero (but it could
701       be shared under some  conditions),  containing  the  joined  path.  The
702       caller  must add a reference count to the value before using it. If any
703       of the values passed into this function (pathPtr or path elements) have
704       a  reference  count  of zero, they will be freed when this function re‐
705       turns.
706
707       Tcl_FSConvertToPathType tries to convert the given Tcl_Obj to  a  valid
708       Tcl path type, taking account of the fact that the cwd may have changed
709       even if this value is already supposedly  of  the  correct  type.   The
710       filename may begin with “~” (to indicate current user's home directory)
711       or “~<user>” (to indicate any user's home directory).
712
713       If the conversion succeeds (i.e. the value is a valid path  in  one  of
714       the  current filesystems), then TCL_OK is returned. Otherwise TCL_ERROR
715       is returned, and an error message may be left in the interpreter.
716
717       Tcl_FSGetInternalRep extracts the internal representation  of  a  given
718       path  value,  in  the  given filesystem. If the path value belongs to a
719       different filesystem, we return NULL. If the internal representation is
720       currently  NULL, we attempt to generate it, by calling the filesystem's
721       Tcl_FSCreateInternalRepProc.
722
723       Returns NULL or a valid internal  path  representation.  This  internal
724       representation  is cached, so that repeated calls to this function will
725       not require additional conversions.
726
727       Tcl_FSGetTranslatedPath attempts to extract the  translated  path  from
728       the given Tcl_Obj.
729
730       If  the  translation succeeds (i.e. the value is a valid path), then it
731       is returned. Otherwise NULL will be returned, and an error message  may
732       be  left  in the interpreter. A “translated” path is one which contains
733       no “~” or “~user” sequences (these have been expanded to their  current
734       representation  in  the filesystem). The value returned is owned by the
735       caller, which must store it or call Tcl_DecrRefCount to  ensure  memory
736       is  freed.  This function is of little practical use, and Tcl_FSGetNor‐
737       malizedPath or Tcl_FSGetNativePath are usually better functions to  use
738       for most purposes.
739
740       Tcl_FSGetTranslatedStringPath does the same as Tcl_FSGetTranslatedPath,
741       but returns a character string or NULL.  The string returned is dynami‐
742       cally  allocated  and  owned by the caller, which must store it or call
743       ckfree to ensure it is freed. Again, Tcl_FSGetNormalizedPath or Tcl_FS‐
744       GetNativePath are usually better functions to use for most purposes.
745
746       Tcl_FSNewNativePath  performs  something  like the reverse of the usual
747       obj->path->nativerep conversions. If some code retrieves a path in  na‐
748       tive form (from, e.g. readlink or a native dialog), and that path is to
749       be used at the Tcl level, then calling this function  is  an  efficient
750       way of creating the appropriate path value type.
751
752       The  resulting  value is a pure “path” value, which will only receive a
753       UTF-8 string representation if that is required by some Tcl code.
754
755       Tcl_FSGetNativePath is for use by the Win/Unix native  filesystems,  so
756       that  they can easily retrieve the native (char* or TCHAR*) representa‐
757       tion of a path. This function is a convenience wrapper  around  Tcl_FS‐
758       GetInternalRep.  It  may be desirable in the future to have non-string-
759       based native representations (for example, on MacOSX, a  representation
760       using  a fileSpec of FSRef structure would probably be more efficient).
761       On Windows a full Unicode representation would allow for paths  of  un‐
762       limited  length.  Currently  the  representation  is simply a character
763       string which may contain either the relative path or a complete,  abso‐
764       lute normalized path in the native encoding (complex conditions dictate
765       which of these will be provided, so neither can be relied upon,  unless
766       the path is known to be absolute). If you need a native path which must
767       be absolute, then you should ask for the native version of a normalized
768       path.  If for some reason a non-absolute, non-normalized version of the
769       path is needed, that must be constructed separately (e.g. using Tcl_FS‐
770       GetTranslatedPath).
771
772       The  native  representation  is  cached  so that repeated calls to this
773       function will not require additional conversions. The return  value  is
774       owned  by  Tcl  and  has  a  lifetime equivalent to that of the pathPtr
775       passed in (unless that is a relative path, in  which  case  the  native
776       representation may be freed any time the cwd changes).
777
778       Tcl_FSFileSystemInfo  returns a list of two elements. The first element
779       is the name  of  the  filesystem  (e.g.   “native”,  “vfs”,  “zip”,  or
780       “prowrap”, perhaps), and the second is the particular type of the given
781       path within that filesystem (which is filesystem dependent). The second
782       element may be empty if the filesystem does not provide a further cate‐
783       gorization of files.
784
785       A valid list value is returned, unless the path  value  is  not  recog‐
786       nized, when NULL will be returned.
787
788       Tcl_FSGetFileSystemForPath  returns  a  pointer  to  the Tcl_Filesystem
789       which accepts this path as valid.
790
791       If no filesystem will accept the path, NULL is returned.
792
793       Tcl_FSGetPathType determines whether the given path is relative to  the
794       current directory, relative to the current volume, or absolute.
795
796       It    returns   one   of   TCL_PATH_ABSOLUTE,   TCL_PATH_RELATIVE,   or
797       TCL_PATH_VOLUME_RELATIVE
798
799   PORTABLE STAT RESULT API
800       Tcl_AllocStatBuf allocates a Tcl_StatBuf on the system heap (which  may
801       be  deallocated  by  being passed to ckfree). This allows extensions to
802       invoke Tcl_FSStat and Tcl_FSLstat without being dependent on  the  size
803       of the buffer. That in turn depends on the flags used to build Tcl.
804
805       The  portable  fields  of a Tcl_StatBuf may be read using the following │
806       functions, each of which returns the value of the  corresponding  field │
807       listed  in  the  table  below. Note that on some platforms there may be │
808       other fields in the Tcl_StatBuf as it is an alias for a suitable system │
809       structure, but only the portable ones are made available here. See your │
810       system documentation for a full description of these fields.            │
811
812              Access Function                    Field
813               Tcl_GetFSDeviceFromStat            st_dev                       │
814               Tcl_GetFSInodeFromStat             st_ino                       │
815               Tcl_GetModeFromStat                st_mode                      │
816               Tcl_GetLinkCountFromStat           st_nlink                     │
817               Tcl_GetUserIdFromStat              st_uid                       │
818               Tcl_GetGroupIdFromStat             st_gid                       │
819               Tcl_GetDeviceTypeFromStat          st_rdev                      │
820               Tcl_GetAccessTimeFromStat          st_atime                     │
821               Tcl_GetModificationTimeFromStat    st_mtime                     │
822               Tcl_GetChangeTimeFromStat          st_ctime                     │
823               Tcl_GetSizeFromStat                st_size                      │
824               Tcl_GetBlocksFromStat              st_blocks                    │
825               Tcl_GetBlockSizeFromStat           st_blksize                   │
826
827

THE VIRTUAL FILESYSTEM API

829       A filesystem provides a Tcl_Filesystem structure that contains pointers
830       to  functions  that  implement  the various operations on a filesystem;
831       these operations are invoked as needed by the generic layer, which gen‐
832       erally occurs through the functions listed above.
833
834       The Tcl_Filesystem structures are manipulated using the following meth‐
835       ods.
836
837       Tcl_FSRegister takes a pointer to a filesystem  structure  and  an  op‐
838       tional  piece  of  data  to associated with that filesystem. On calling
839       this function, Tcl will attach the filesystem  to  the  list  of  known
840       filesystems,  and it will become fully functional immediately. Tcl does
841       not check if the same filesystem is registered multiple times  (and  in
842       general that is not a good thing to do). TCL_OK will be returned.
843
844       Tcl_FSUnregister  removes  the given filesystem structure from the list
845       of known filesystems, if it  is  known,  and  returns  TCL_OK.  If  the
846       filesystem is not currently registered, TCL_ERROR is returned.
847
848       Tcl_FSData  will  return  the  ClientData  associated  with  the  given
849       filesystem, if that filesystem is registered. Otherwise it will  return
850       NULL.
851
852       Tcl_FSMountsChanged  is  used  to inform the Tcl's core that the set of
853       mount  points  for  the  given  (already  registered)  filesystem  have
854       changed,  and  that cached file representations may therefore no longer
855       be correct.
856
857   THE TCL_FILESYSTEM STRUCTURE
858       The Tcl_Filesystem structure contains the following fields:
859
860              typedef struct Tcl_Filesystem {
861                  const char *typeName;
862                  int structureLength;
863                  Tcl_FSVersion version;
864                  Tcl_FSPathInFilesystemProc *pathInFilesystemProc;
865                  Tcl_FSDupInternalRepProc *dupInternalRepProc;
866                  Tcl_FSFreeInternalRepProc *freeInternalRepProc;
867                  Tcl_FSInternalToNormalizedProc *internalToNormalizedProc;
868                  Tcl_FSCreateInternalRepProc *createInternalRepProc;
869                  Tcl_FSNormalizePathProc *normalizePathProc;
870                  Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc;
871                  Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc;
872                  Tcl_FSStatProc *statProc;
873                  Tcl_FSAccessProc *accessProc;
874                  Tcl_FSOpenFileChannelProc *openFileChannelProc;
875                  Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
876                  Tcl_FSUtimeProc *utimeProc;
877                  Tcl_FSLinkProc *linkProc;
878                  Tcl_FSListVolumesProc *listVolumesProc;
879                  Tcl_FSFileAttrStringsProc *fileAttrStringsProc;
880                  Tcl_FSFileAttrsGetProc *fileAttrsGetProc;
881                  Tcl_FSFileAttrsSetProc *fileAttrsSetProc;
882                  Tcl_FSCreateDirectoryProc *createDirectoryProc;
883                  Tcl_FSRemoveDirectoryProc *removeDirectoryProc;
884                  Tcl_FSDeleteFileProc *deleteFileProc;
885                  Tcl_FSCopyFileProc *copyFileProc;
886                  Tcl_FSRenameFileProc *renameFileProc;
887                  Tcl_FSCopyDirectoryProc *copyDirectoryProc;
888                  Tcl_FSLstatProc *lstatProc;
889                  Tcl_FSLoadFileProc *loadFileProc;
890                  Tcl_FSGetCwdProc *getCwdProc;
891                  Tcl_FSChdirProc *chdirProc;
892              } Tcl_Filesystem;
893
894       Except for the first three fields in this structure which contain  sim‐
895       ple data elements, all entries contain addresses of functions called by
896       the generic filesystem layer to perform the complete range of  filesys‐
897       tem related actions.
898
899       The  many  functions in this structure are broken down into three cate‐
900       gories: infrastructure functions (almost all of which  must  be  imple‐
901       mented), operational functions (which must be implemented if a complete
902       filesystem is provided), and efficiency functions (which need  only  be
903       implemented  if  they can be done so efficiently, or if they have side-
904       effects which are required by the filesystem; Tcl  has  less  efficient
905       emulations  it  can fall back on). It is important to note that, in the
906       current version of Tcl, most of these fallbacks are only used to handle
907       commands initiated in Tcl, not in C. What this means is, that if a file
908       rename command is issued in Tcl, and the relevant filesystem(s) do  not
909       implement  their Tcl_FSRenameFileProc, Tcl's core will instead fallback
910       on a combination of other filesystem functions (it will use Tcl_FSCopy‐
911       FileProc followed by Tcl_FSDeleteFileProc, and if Tcl_FSCopyFileProc is
912       not implemented there is a further fallback). However, if  a  Tcl_FSRe‐
913       nameFileProc command is issued at the C level, no such fallbacks occur.
914       This is true except for the last four entries in the  filesystem  table
915       (lstat, load, getcwd and chdir) for which fallbacks do in fact occur at
916       the C level.
917
918       Any functions which take path names in Tcl_Obj form take those names in
919       UTF-8  form.  The  filesystem infrastructure API is designed to support
920       efficient, cached conversion of these UTF-8 paths to other native  rep‐
921       resentations.
922
923   EXAMPLE FILESYSTEM DEFINITION
924       Here  is  the filesystem lookup table used by the “vfs” extension which
925       allows filesystem actions to be implemented in Tcl.
926
927              static Tcl_Filesystem vfsFilesystem = {
928                  "tclvfs",
929                  sizeof(Tcl_Filesystem),
930                  TCL_FILESYSTEM_VERSION_1,
931                  &VfsPathInFilesystem,
932                  &VfsDupInternalRep,
933                  &VfsFreeInternalRep,
934                  /* No internal to normalized, since we don't create
935                   * any pure 'internal' Tcl_Obj path representations */
936                  NULL,
937                  /* No create native rep function, since we don't use
938                   * it and don't choose to support uses of
939                   * Tcl_FSNewNativePath */
940                  NULL,
941                  /* Normalize path isn't needed - we assume paths only
942                   * have one representation */
943                  NULL,
944                  &VfsFilesystemPathType,
945                  &VfsFilesystemSeparator,
946                  &VfsStat,
947                  &VfsAccess,
948                  &VfsOpenFileChannel,
949                  &VfsMatchInDirectory,
950                  &VfsUtime,
951                  /* We choose not to support symbolic links inside our
952                   * VFS's */
953                  NULL,
954                  &VfsListVolumes,
955                  &VfsFileAttrStrings,
956                  &VfsFileAttrsGet,
957                  &VfsFileAttrsSet,
958                  &VfsCreateDirectory,
959                  &VfsRemoveDirectory,
960                  &VfsDeleteFile,
961                  /* No copy file; use the core fallback mechanism */
962                  NULL,
963                  /* No rename file; use the core fallback mechanism */
964                  NULL,
965                  /* No copy directory; use the core fallback mechanism */
966                  NULL,
967                  /* Core will use stat for lstat */
968                  NULL,
969                  /* No load; use the core fallback mechanism */
970                  NULL,
971                  /* We don't need a getcwd or chdir; the core's own
972                   * internal value is suitable */
973                  NULL,
974                  NULL
975              };
976

FILESYSTEM INFRASTRUCTURE

978       These fields contain basic information about the  filesystem  structure
979       and  addresses  of  functions  which are used to associate a particular
980       filesystem with a file path, and deal with  the  internal  handling  of
981       path  representations, for example copying and freeing such representa‐
982       tions.
983
984   TYPENAME
985       The typeName field contains a null-terminated  string  that  identifies
986       the type of the filesystem implemented, e.g.  “native”, “zip” or “vfs”.
987
988   STRUCTURE LENGTH
989       The    structureLength    field    is    generally    implemented    as
990       sizeof(Tcl_Filesystem), and is there to allow easier  binary  backwards
991       compatibility  if the size of the structure changes in a future Tcl re‐
992       lease.
993
994   VERSION
995       The version field should be set to TCL_FILESYSTEM_VERSION_1.
996
997   PATHINFILESYSTEMPROC
998       The pathInFilesystemProc field contains the address of a function which
999       is  called  to  determine  whether  a  given path value belongs to this
1000       filesystem or not. Tcl will only call the rest of the filesystem  func‐
1001       tions  with a path for which this function has returned TCL_OK.  If the
1002       path does not belong, -1 should be returned (the behavior  of  Tcl  for
1003       any other return value is not defined). If TCL_OK is returned, then the
1004       optional clientDataPtr output parameter can be used to return an inter‐
1005       nal  (filesystem  specific)  representation  of the path, which will be
1006       cached inside the path value, and may be retrieved efficiently  by  the
1007       other filesystem functions. Tcl will simultaneously cache the fact that
1008       this path belongs to this filesystem. Such caches are invalidated  when
1009       filesystem  structures are added or removed from Tcl's internal list of
1010       known filesystems.
1011
1012              typedef int Tcl_FSPathInFilesystemProc(
1013                      Tcl_Obj *pathPtr,
1014                      ClientData *clientDataPtr);
1015
1016   DUPINTERNALREPPROC
1017       This function makes a copy of a path's internal representation, and  is
1018       called when Tcl needs to duplicate a path value. If NULL, Tcl will sim‐
1019       ply not copy the internal representation, which may then need to be re‐
1020       generated later.
1021
1022              typedef ClientData Tcl_FSDupInternalRepProc(
1023                      ClientData clientData);
1024
1025   FREEINTERNALREPPROC
1026       Free  the internal representation. This must be implemented if internal
1027       representations need freeing (i.e. if some memory is allocated when  an
1028       internal representation is generated), but may otherwise be NULL.
1029
1030              typedef void Tcl_FSFreeInternalRepProc(
1031                      ClientData clientData);
1032
1033   INTERNALTONORMALIZEDPROC
1034       Function  to convert internal representation to a normalized path. Only
1035       required if the filesystem creates pure path values with no string/path
1036       representation.  The return value is a Tcl value whose string represen‐
1037       tation is the normalized path.
1038
1039              typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc(
1040                      ClientData clientData);
1041
1042   CREATEINTERNALREPPROC
1043       Function to take a path value, and calculate an internal representation
1044       for  it, and store that native representation in the value. May be NULL
1045       if paths have no  internal  representation,  or  if  the  Tcl_FSPathIn‐
1046       FilesystemProc for this filesystem always immediately creates an inter‐
1047       nal representation for paths it accepts.
1048
1049              typedef ClientData Tcl_FSCreateInternalRepProc(
1050                      Tcl_Obj *pathPtr);
1051
1052   NORMALIZEPATHPROC
1053       Function to normalize a path. Should be implemented for all filesystems
1054       which can have multiple string representations for the same path value.
1055       In Tcl, every “path” must have a single unique “normalized” string rep‐
1056       resentation.  Depending  on  the filesystem, there may be more than one
1057       unnormalized string representation which refers to  that  path  (e.g. a
1058       relative  path,  a path with different character case if the filesystem
1059       is case insensitive, a path contain a reference  to  a  home  directory
1060       such  as  “~”, a path containing symbolic links, etc). If the very last
1061       component in the path is a symbolic link, it should  not  be  converted
1062       into  the  value  it points to (but its case or other aspects should be
1063       made unique). All other path components should be converted  from  sym‐
1064       bolic  links. This one exception is required to agree with Tcl's seman‐
1065       tics with file delete, file rename, file  copy  operating  on  symbolic
1066       links.   This  function may be called with nextCheckpoint either at the
1067       beginning of the path (i.e. zero), at the end of the path,  or  at  any
1068       intermediate  file  separator  in  the path. It will never point to any
1069       other arbitrary position in the path. In the last of  the  three  valid
1070       cases,  the implementation can assume that the path up to and including
1071       the file separator is known and normalized.
1072
1073              typedef int Tcl_FSNormalizePathProc(
1074                      Tcl_Interp *interp,
1075                      Tcl_Obj *pathPtr,
1076                      int nextCheckpoint);
1077

FILESYSTEM OPERATIONS

1079       The fields in this section of the structure contain addresses of  func‐
1080       tions  which are called to carry out the basic filesystem operations. A
1081       filesystem which expects to be used with the complete standard Tcl com‐
1082       mand  set  must  implement all of these. If some of them are not imple‐
1083       mented, then certain Tcl commands may  fail  when  operating  on  paths
1084       within  that  filesystem. However, in some instances this may be desir‐
1085       able (for example, a read-only filesystem should not implement the last
1086       four  functions, and a filesystem which does not support symbolic links
1087       need not implement the readlink function, etc.  The  Tcl  core  expects
1088       filesystems to behave in this way).
1089
1090   FILESYSTEMPATHTYPEPROC
1091       Function  to  determine  the  type of a path in this filesystem. May be
1092       NULL, in which case no type information will be available to  users  of
1093       the filesystem. The “type” is used only for informational purposes, and
1094       should be returned as the string representation of the Tcl_Obj which is
1095       returned.  A typical return value might be “networked”, “zip” or “ftp”.
1096       The Tcl_Obj result is owned by the filesystem and so Tcl will increment
1097       the reference count of that value if it wishes to retain a reference to
1098       it.
1099
1100              typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc(
1101                      Tcl_Obj *pathPtr);
1102
1103   FILESYSTEMSEPARATORPROC
1104       Function to return the  separator  character(s)  for  this  filesystem.
1105       This need only be implemented if the filesystem wishes to use a differ‐
1106       ent separator than the standard string “/”.  Amongst other uses, it  is
1107       returned  by  the  file separator command. The return value should be a
1108       value with reference count of zero.
1109
1110              typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc(
1111                      Tcl_Obj *pathPtr);
1112
1113   STATPROC
1114       Function to process a Tcl_FSStat call. Must be implemented for any rea‐
1115       sonable filesystem, since many Tcl level commands depend crucially upon
1116       it (e.g. file atime, file isdirectory, file size, glob).
1117
1118              typedef int Tcl_FSStatProc(
1119                      Tcl_Obj *pathPtr,
1120                      Tcl_StatBuf *statPtr);
1121
1122       The Tcl_FSStatProc fills the stat structure  statPtr  with  information
1123       about the specified file. You do not need any access rights to the file
1124       to get this information but you need search rights to  all  directories
1125       named in the path leading to the file. The stat structure includes info
1126       regarding device, inode (always 0 on Windows),  privilege  mode,  nlink
1127       (always  1 on Windows), user id (always 0 on Windows), group id (always
1128       0 on Windows), rdev (same as device  on  Windows),  size,  last  access
1129       time, last modification time, and last metadata change time.
1130
1131       If the file represented by pathPtr exists, the Tcl_FSStatProc returns 0
1132       and the stat structure is filled with data. Otherwise, -1 is  returned,
1133       and no stat info is given.
1134
1135   ACCESSPROC
1136       Function  to  process  a Tcl_FSAccess call. Must be implemented for any
1137       reasonable filesystem, since many Tcl level commands  depend  crucially
1138       upon it (e.g. file exists, file readable).
1139
1140              typedef int Tcl_FSAccessProc(
1141                      Tcl_Obj *pathPtr,
1142                      int mode);
1143
1144       The  Tcl_FSAccessProc  checks  whether  the process would be allowed to
1145       read, write or test for existence of the file (or other filesystem  ob‐
1146       ject)  whose  name  is in pathPtr. If the pathname refers to a symbolic
1147       link, then the permissions of the file referred by this  symbolic  link
1148       should be tested.
1149
1150       On  success  (all  requested permissions granted), zero is returned. On
1151       error (at least one bit in mode asked for a permission that is  denied,
1152       or some other  error occurred), -1 is returned.
1153
1154   OPENFILECHANNELPROC
1155       Function  to  process a Tcl_FSOpenFileChannel call. Must be implemented
1156       for any reasonable filesystem, since any operations which require  open
1157       or  accessing  a  file's contents will use it (e.g. open, encoding, and
1158       many Tk commands).
1159
1160              typedef Tcl_Channel Tcl_FSOpenFileChannelProc(
1161                      Tcl_Interp *interp,
1162                      Tcl_Obj *pathPtr,
1163                      int mode,
1164                      int permissions);
1165
1166       The Tcl_FSOpenFileChannelProc opens a file specified by pathPtr and re‐
1167       turns  a channel handle that can be used to perform input and output on
1168       the file. This API is modeled after the fopen  procedure  of  the  Unix
1169       standard  I/O library. The syntax and meaning of all arguments is simi‐
1170       lar to those given in the Tcl open command when opening a  file,  where
1171       the  mode  argument  is  a  combination  of  the  POSIX flags O_RDONLY,
1172       O_WRONLY, etc. If an  error  occurs  while  opening  the  channel,  the
1173       Tcl_FSOpenFileChannelProc  returns  NULL and records a POSIX error code
1174       that can be retrieved with Tcl_GetErrno.  In  addition,  if  interp  is
1175       non-NULL,  the Tcl_FSOpenFileChannelProc leaves an error message in in‐
1176       terp's result after any error.
1177
1178       The newly created channel must not be registered in the supplied inter‐
1179       preter by a Tcl_FSOpenFileChannelProc; that task is up to the caller of
1180       Tcl_FSOpenFileChannel (if necessary). If one of the standard  channels,
1181       stdin,  stdout or stderr was previously closed, the act of creating the
1182       new channel also assigns it as a replacement for the standard channel.
1183
1184   MATCHINDIRECTORYPROC
1185       Function to process a Tcl_FSMatchInDirectory call. If not  implemented,
1186       then  glob  and  recursive  copy  functionality  will be lacking in the
1187       filesystem (and this may impact commands like encoding names which  use
1188       glob functionality internally).
1189
1190              typedef int Tcl_FSMatchInDirectoryProc(
1191                      Tcl_Interp *interp,
1192                      Tcl_Obj *resultPtr,
1193                      Tcl_Obj *pathPtr,
1194                      const char *pattern,
1195                      Tcl_GlobTypeData *types);
1196
1197       The  function should return all files or directories (or other filesys‐
1198       tem objects) which match the given pattern and accord  with  the  types
1199       specification  given.  There are two ways in which this function may be
1200       called. If pattern is NULL, then pathPtr is a full  path  specification
1201       of a single file or directory which should be checked for existence and
1202       correct type. Otherwise, pathPtr is a directory, the contents of  which
1203       the function should search for files or directories which have the cor‐
1204       rect type. In either case, pathPtr can be assumed to be  both  non-NULL
1205       and non-empty. It is not currently documented whether pathPtr will have
1206       a file separator at its end of not, so code should be flexible to  both
1207       possibilities.
1208
1209       The  return  value is a standard Tcl result indicating whether an error
1210       occurred in the matching process. Error messages are placed in  interp,
1211       unless interp in NULL in which case no error message need be generated;
1212       on a TCL_OK result, results should be  added  to  the  resultPtr  value
1213       given  (which  can  be  assumed  to  be a valid unshared Tcl list). The
1214       matches added to resultPtr should include  any  path  prefix  given  in
1215       pathPtr (this usually means they will be absolute path specifications).
1216       Note that if no matches are found, that simply leads to  an  empty  re‐
1217       sult;  errors  are only signaled for actual file or filesystem problems
1218       which may occur during the matching process.
1219
1220       The Tcl_GlobTypeData structure passed in the types  parameter  contains
1221       the following fields:
1222
1223              typedef struct Tcl_GlobTypeData {
1224                  /* Corresponds to bcdpfls as in 'find -t' */
1225                  int type;
1226                  /* Corresponds to file permissions */
1227                  int perm;
1228                  /* Acceptable mac type */
1229                  Tcl_Obj *macType;
1230                  /* Acceptable mac creator */
1231                  Tcl_Obj *macCreator;
1232              } Tcl_GlobTypeData;
1233
1234       There are two specific cases which it is important to handle correctly,
1235       both when types is non-NULL. The two  cases  are  when  types->types  &
1236       TCL_GLOB_TYPE_DIR  or  types->types & TCL_GLOB_TYPE_MOUNT are true (and
1237       in particular when the other flags are false). In the  first  of  these
1238       cases,  the function must list the contained directories. Tcl uses this
1239       to implement recursive globbing, so it is critical that filesystems im‐
1240       plement  directory  matching  correctly.  In the second of these cases,
1241       with TCL_GLOB_TYPE_MOUNT, the filesystem must  list  the  mount  points
1242       which  lie within the given pathPtr (and in this case, pathPtr need not
1243       lie within the same filesystem - different to all other cases in  which
1244       this  function  is  called).  Support for this is critical if Tcl is to
1245       have seamless transitions between from one filesystem to another.
1246
1247   UTIMEPROC
1248       Function to process a Tcl_FSUtime call. Required to allow setting  (not
1249       reading)  of  times  with  file  mtime, file atime and the open-r/open-
1250       w/fcopy implementation of file copy.
1251
1252              typedef int Tcl_FSUtimeProc(
1253                      Tcl_Obj *pathPtr,
1254                      struct utimbuf *tval);
1255
1256       The access and modification times of  the  file  specified  by  pathPtr
1257       should be changed to the values given in the tval structure.
1258
1259       The return value should be 0 on success and -1 on an error, as with the
1260       system utime.
1261
1262   LINKPROC
1263       Function to process a Tcl_FSLink call. Should be  implemented  only  if
1264       the filesystem supports links, and may otherwise be NULL.
1265
1266              typedef Tcl_Obj *Tcl_FSLinkProc(
1267                      Tcl_Obj *linkNamePtr,
1268                      Tcl_Obj *toPtr,
1269                      int linkAction);
1270
1271       If toPtr is NULL, the function is being asked to read the contents of a
1272       link. The result is a Tcl_Obj specifying the contents of the link given
1273       by  linkNamePtr,  or  NULL if the link could not be read. The result is
1274       owned by the caller (and should therefore have  its  ref  count  incre‐
1275       mented before being returned). Any callers should call Tcl_DecrRefCount
1276       on this result when it is no longer needed.  If toPtr is not NULL,  the
1277       function  should  attempt  to  create  a link.  The result in this case
1278       should be toPtr if the link was successful and NULL otherwise. In  this
1279       case the result is not owned by the caller (i.e. no reference count ma‐
1280       nipulations on either  end  are  needed).  See  the  documentation  for
1281       Tcl_FSLink for the correct interpretation of the linkAction flags.
1282
1283   LISTVOLUMESPROC
1284       Function  to  list  any  filesystem  volumes  added by this filesystem.
1285       Should be implemented only if the filesystem adds volumes at  the  head
1286       of the filesystem, so that they can be returned by file volumes.
1287
1288              typedef Tcl_Obj *Tcl_FSListVolumesProc(void);
1289
1290       The  result  should  be  a list of volumes added by this filesystem, or
1291       NULL (or an empty list) if no volumes are provided. The result value is
1292       considered  to  be  owned  by  the  filesystem (not by Tcl's core), but
1293       should be given a reference count for Tcl. Tcl will use the contents of
1294       the  list and then decrement that reference count. This allows filesys‐
1295       tems to choose whether they actually want to retain a “global list”  of
1296       volumes  or  not (if not, they generate the list on the fly and pass it
1297       to Tcl with a reference count of 1 and then forget about the  list,  if
1298       yes,  then  they  simply  increment the reference count of their global
1299       list and pass it to Tcl which will copy the contents and then decrement
1300       the count back to where it was).
1301
1302       Therefore, Tcl considers return values from this proc to be read-only.
1303
1304   FILEATTRSTRINGSPROC
1305       Function  to  list  all  attribute  strings  which  are  valid for this
1306       filesystem. If not implemented the filesystem will not support the file
1307       attributes  command. This allows arbitrary additional information to be
1308       attached to files in the filesystem. If it is not implemented, there is
1309       no need to implement the get and set methods.
1310
1311              typedef const char *const *Tcl_FSFileAttrStringsProc(
1312                      Tcl_Obj *pathPtr,
1313                      Tcl_Obj **objPtrRef);
1314
1315       The  called  function may either return an array of strings, or may in‐
1316       stead return NULL and place a Tcl list into the  given  objPtrRef.  Tcl
1317       will  take that list and first increment its reference count before us‐
1318       ing it.  On completion of that use, Tcl will  decrement  its  reference
1319       count.  Hence  if  the  list should be disposed of by Tcl when done, it
1320       should have a reference count of zero, and if the list  should  not  be
1321       disposed  of,  the  filesystem  should ensure it returns a value with a
1322       reference count of at least one.
1323
1324   FILEATTRSGETPROC
1325       Function to process a Tcl_FSFileAttrsGet call, used by file attributes.
1326
1327              typedef int Tcl_FSFileAttrsGetProc(
1328                      Tcl_Interp *interp,
1329                      int index,
1330                      Tcl_Obj *pathPtr,
1331                      Tcl_Obj **objPtrRef);
1332
1333       Returns a standard Tcl return  code.  The  attribute  value  retrieved,
1334       which  corresponds  to the index'th element in the list returned by the
1335       Tcl_FSFileAttrStringsProc, is a Tcl_Obj placed in objPtrRef (if  TCL_OK
1336       was  returned)  and is likely to have a reference count of zero. Either
1337       way we must  either  store  it  somewhere  (e.g. the  Tcl  result),  or
1338       Incr/Decr its reference count to ensure it is properly freed.
1339
1340   FILEATTRSSETPROC
1341       Function to process a Tcl_FSFileAttrsSet call, used by file attributes.
1342       If the filesystem is read-only, there is no need to implement this.
1343
1344              typedef int Tcl_FSFileAttrsSetProc(
1345                      Tcl_Interp *interp,
1346                      int index,
1347                      Tcl_Obj *pathPtr,
1348                      Tcl_Obj *objPtr);
1349
1350       The attribute value of the index'th element in the list returned by the
1351       Tcl_FSFileAttrStringsProc should be set to the objPtr given.
1352
1353   CREATEDIRECTORYPROC
1354       Function to process a Tcl_FSCreateDirectory call. Should be implemented
1355       unless the FS is read-only.
1356
1357              typedef int Tcl_FSCreateDirectoryProc(
1358                      Tcl_Obj *pathPtr);
1359
1360       The return value is a standard Tcl result indicating whether  an  error
1361       occurred  in  the  process.  If successful, a new directory should have
1362       been added to the filesystem in the location specified by pathPtr.
1363
1364   REMOVEDIRECTORYPROC
1365       Function to process a Tcl_FSRemoveDirectory call. Should be implemented
1366       unless the FS is read-only.
1367
1368              typedef int Tcl_FSRemoveDirectoryProc(
1369                      Tcl_Obj *pathPtr,
1370                      int recursive,
1371                      Tcl_Obj **errorPtr);
1372
1373       The  return  value is a standard Tcl result indicating whether an error
1374       occurred in the process. If  successful,  the  directory  specified  by
1375       pathPtr  should have been removed from the filesystem. If the recursive
1376       flag is given, then a non-empty directory should be deleted without er‐
1377       ror.  If  this flag is not given, then and the directory is non-empty a
1378       POSIX “EEXIST” error should be signaled. If an error  does  occur,  the
1379       name  of  the file or directory which caused the error should be placed
1380       in errorPtr.
1381
1382   DELETEFILEPROC
1383       Function to process a Tcl_FSDeleteFile call. Should be implemented  un‐
1384       less the FS is read-only.
1385
1386              typedef int Tcl_FSDeleteFileProc(
1387                      Tcl_Obj *pathPtr);
1388
1389       The  return  value is a standard Tcl result indicating whether an error
1390       occurred in the process. If successful, the file specified  by  pathPtr
1391       should  have  been  removed  from  the  filesystem.  Note  that, if the
1392       filesystem supports symbolic links, Tcl will always call this  function
1393       and  not  Tcl_FSRemoveDirectoryProc when needed to delete them (even if
1394       they are symbolic links to directories).
1395

FILESYSTEM EFFICIENCY

1397       These functions need not be implemented for a particular filesystem be‐
1398       cause  the core has a fallback implementation available. See each indi‐
1399       vidual description for the consequences of leaving the field NULL.
1400
1401   LSTATPROC
1402       Function to process a Tcl_FSLstat call. If not  implemented,  Tcl  will
1403       attempt  to  use  the statProc defined above instead. Therefore it need
1404       only be implemented if a filesystem can differentiate between stat  and
1405       lstat calls.
1406
1407              typedef int Tcl_FSLstatProc(
1408                      Tcl_Obj *pathPtr,
1409                      Tcl_StatBuf *statPtr);
1410
1411       The  behavior  of  this  function  is  very  similar  to  that  of  the
1412       Tcl_FSStatProc defined above, except that if it is applied  to  a  sym‐
1413       bolic link, it returns information about the link, not about the target
1414       file.
1415
1416   COPYFILEPROC
1417       Function to process a Tcl_FSCopyFile call. If not implemented Tcl  will
1418       fall  back  on open-r, open-w and fcopy as a copying mechanism.  There‐
1419       fore it need only be implemented if the filesystem can perform that ac‐
1420       tion more efficiently.
1421
1422              typedef int Tcl_FSCopyFileProc(
1423                      Tcl_Obj *srcPathPtr,
1424                      Tcl_Obj *destPathPtr);
1425
1426       The  return  value is a standard Tcl result indicating whether an error
1427       occurred in the copying process. Note that, destPathPtr is the name  of
1428       the  file  which  should become the copy of srcPathPtr. It is never the
1429       name of a directory into which srcPathPtr  could  be  copied  (i.e. the
1430       function is much simpler than the Tcl level file copy subcommand). Note
1431       that, if the filesystem supports symbolic links, Tcl will  always  call
1432       this  function and not copyDirectoryProc when needed to copy them (even
1433       if they are symbolic links to directories). Finally, if the  filesystem
1434       determines  it  cannot support the file copy action, calling Tcl_SetEr‐
1435       rno(EXDEV) and returning a non-TCL_OK result will tell Tcl to  use  its
1436       standard fallback mechanisms.
1437
1438   RENAMEFILEPROC
1439       Function  to  process  a Tcl_FSRenameFile call. If not implemented, Tcl
1440       will fall back on a copy and delete mechanism. Therefore it  need  only
1441       be  implemented  if  the  filesystem can perform that action more effi‐
1442       ciently.
1443
1444              typedef int Tcl_FSRenameFileProc(
1445                      Tcl_Obj *srcPathPtr,
1446                      Tcl_Obj *destPathPtr);
1447
1448       The return value is a standard Tcl result indicating whether  an  error
1449       occurred  in the renaming process. If the filesystem determines it can‐
1450       not support the file rename action, calling Tcl_SetErrno(EXDEV) and re‐
1451       turning  a non-TCL_OK result will tell Tcl to use its standard fallback
1452       mechanisms.
1453
1454   COPYDIRECTORYPROC
1455       Function to process a Tcl_FSCopyDirectory call. If not implemented, Tcl
1456       will  fall  back on a recursive file mkdir, file copy mechanism. There‐
1457       fore it need only be implemented if the filesystem can perform that ac‐
1458       tion more efficiently.
1459
1460              typedef int Tcl_FSCopyDirectoryProc(
1461                      Tcl_Obj *srcPathPtr,
1462                      Tcl_Obj *destPathPtr,
1463                      Tcl_Obj **errorPtr);
1464
1465       The  return  value is a standard Tcl result indicating whether an error
1466       occurred in the copying process. If an error does occur,  the  name  of
1467       the  file  or  directory which caused the error should be placed in er‐
1468       rorPtr. Note that, destPathPtr is the name of the directory-name  which
1469       should  become  the mirror-image of srcPathPtr. It is not the name of a
1470       directory into which srcPathPtr should be copied (i.e. the function  is
1471       much  simpler than the Tcl level file copy subcommand). Finally, if the
1472       filesystem determines it cannot  support  the  directory  copy  action,
1473       calling Tcl_SetErrno(EXDEV) and returning a non-TCL_OK result will tell
1474       Tcl to use its standard fallback mechanisms.
1475
1476   LOADFILEPROC
1477       Function to process a Tcl_FSLoadFile call. If not implemented, Tcl will
1478       fall back on a copy to native-temp followed by a Tcl_FSLoadFile on that
1479       temporary copy. Therefore it need only be implemented if the filesystem
1480       can  load  code  directly,  or  it  can be implemented simply to return
1481       TCL_ERROR to disable load functionality in this filesystem entirely.
1482
1483              typedef int Tcl_FSLoadFileProc(
1484                      Tcl_Interp *interp,
1485                      Tcl_Obj *pathPtr,
1486                      Tcl_LoadHandle *handlePtr,
1487                      Tcl_FSUnloadFileProc *unloadProcPtr);
1488
1489       Returns a standard Tcl completion code. If an error  occurs,  an  error
1490       message  is left in the interp's result. The function dynamically loads
1491       a binary code file into memory. On a  successful  load,  the  handlePtr
1492       should  be filled with a token for the dynamically loaded file, and the
1493       unloadProcPtr should be filled in with the address of a procedure.  The
1494       unload  procedure  will  be called with the given Tcl_LoadHandle as its
1495       only parameter when Tcl needs to unload the file. For example, for  the
1496       native  filesystem,  the  Tcl_LoadHandle  returned is currently a token
1497       which can be used in the private TclpFindSymbol to access functions  in
1498       the  new  code. Each filesystem is free to define the Tcl_LoadHandle as
1499       it requires. Finally, if the filesystem determines  it  cannot  support
1500       the  file load action, calling Tcl_SetErrno(EXDEV) and returning a non-
1501       TCL_OK result will tell Tcl to use its standard fallback mechanisms.
1502
1503   UNLOADFILEPROC
1504       Function to unload a previously successfully loaded file. If  load  was
1505       implemented,  then  this  should  also  be implemented, if there is any
1506       cleanup action required.
1507
1508              typedef void Tcl_FSUnloadFileProc(
1509                      Tcl_LoadHandle loadHandle);
1510
1511   GETCWDPROC
1512       Function to process a Tcl_FSGetCwd call. Most filesystems need not  im‐
1513       plement  this. It will usually only be called once, if getcwd is called
1514       before chdir. May be NULL.
1515
1516              typedef Tcl_Obj *Tcl_FSGetCwdProc(
1517                      Tcl_Interp *interp);
1518
1519       If the filesystem supports a native notion of a current working  direc‐
1520       tory  (which  might  perhaps  change independent of Tcl), this function
1521       should return that cwd as the result, or NULL if the current  directory
1522       could  not  be determined (e.g. the user does not have appropriate per‐
1523       missions on the cwd directory). If NULL is returned, an  error  message
1524       is left in the interp's result.
1525
1526   CHDIRPROC
1527       Function to process a Tcl_FSChdir call. If filesystems do not implement
1528       this, it will be emulated by a series of directory access checks.  Oth‐
1529       erwise,  virtual  filesystems  which  do implement it need only respond
1530       with a positive return result if the pathPtr is a valid, accessible di‐
1531       rectory  in  their filesystem. They need not remember the result, since
1532       that will be automatically remembered for use  by  Tcl_FSGetCwd.   Real
1533       filesystems  should carry out the correct action (i.e. call the correct
1534       system chdir API).
1535
1536              typedef int Tcl_FSChdirProc(
1537                      Tcl_Obj *pathPtr);
1538
1539       The Tcl_FSChdirProc changes the applications current working  directory
1540       to  the value specified in pathPtr. The function returns -1 on error or
1541       0 on success.
1542

SEE ALSO

1544       cd(n), file(n), filename(n), load(n), open(n), pwd(n),  source(n),  un‐
1545       load(n)
1546

KEYWORDS

1548       stat, access, filesystem, vfs, virtual filesystem
1549
1550
1551
1552Tcl                                   8.4                        Filesystem(3)
Impressum