From: Vince Darley Date: Fri, 21 Feb 2003 11:56:26 +0000 (+0000) Subject: documentation and internalerror handling update X-Git-Tag: vfs-1-3~39 X-Git-Url: http://privyetmir.co.uk/gitweb?a=commitdiff_plain;h=e05ac328b2906ecdf4e323a05e05d65581167809;p=tclvfs documentation and internalerror handling update --- diff --git a/ChangeLog b/ChangeLog index 29ebe79..87155d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-02-20 Vince Darley + + * generic/vfs.c: completed use of internalerror and posix handling + for all functions. + * doc/vfs.n: + * doc/vfslib.n: more documentation regarding handling of errors + and use of the 'internalerror' feature. + + Around the time Tcl 8.4.2 is released we should increment tclvfs's + version to 1.3 and make a proper release. In the meantime, + improvements to all .tcl implementations (esp. proper error + handling) would be greatly appreciated. + 2003-02-20 Andreas Kupries * library/mk4vfs.tcl: Switching to canceling the stored after id diff --git a/doc/vfs.n b/doc/vfs.n index 94bbcf4..81f0322 100644 --- a/doc/vfs.n +++ b/doc/vfs.n @@ -68,10 +68,12 @@ effect is to provide the command \fBvfs::filesystem\fR which allows the interpreter to intercept filesystem commands and handle them with Tcl code in that interpreter. .PP -There are two unsupported subcommands of \fBvfs::filesystem\fR, -\fBfullynormalize path\fR and \fBposixerror int\fR, which are used to -normalize a path (including any final symlink) and to register a posix -error code with a Tcl error, respectively. +There are three somewhat unsupported subcommands of +\fBvfs::filesystem\fR, \fBfullynormalize path\fR, \fBposixerror int\fR, +\fBinternalerror ?script?\fR, 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 implementations +respectively. .TP \fBvfs::filesystem\fR \fImount\fR \fI?-volume?\fR \fIpath\fR \fIcommand\fR To use a virtual filesystem, it must be 'mounted'. Mounting involves @@ -145,13 +147,25 @@ Note that most filesystem operations will only require the \fIrelative\fR argument to work correctly, but the other arguments are actually required for correct operation of some subcommands. .PP +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. +.PP The actual commands are as follows (where \fIr-r-a\fR represents the standard argument triplet of \fIroot\fR, \fIrelative\fR and \fIactualpath\fR): .TP \fIcommand\fR \fIaccess\fR \fIr-r-a\fR \fImode\fR -Return 1 or throw an error depending on whether the given access mode (which -is an integer) is compatible with the file. +Return TCL_OK or throw a posix error depending on whether the given +access mode (which is an integer) is compatible with the file. .TP \fIcommand\fR \fIcreatedirectory\fR \fIr-r-a\fR Create a directory with the given name. @@ -193,7 +207,9 @@ 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). +asycnhronously, with bgerror, for example), unless the 'internalerror' +script has been specified, when they are passed to that script for +further action. .TP \fIcommand\fR \fIremovedirectory\fR \fIr-r-a\fR Delete the given directory. @@ -233,6 +249,12 @@ Returns that subset of the \fIfilelist\fR (which are either absolute paths or names of files in \fIinDir\fR) which are compatible with the \fItypes\fR given. +.SH VFS DEBUGGING +.PP +Use something like this to debug problems in your implementation: +vfs::filesystem internalerror report ; proc report {} { puts +stderr $::errorInfo } + .SH LIMITATIONS .PP There are very few limitations to the vfs code. One subtlety that you diff --git a/generic/vfs.c b/generic/vfs.c index 4f1d2a8..96a3ef1 100644 --- a/generic/vfs.c +++ b/generic/vfs.c @@ -854,12 +854,14 @@ VfsFilesystemObjCmd(dummy, interp, objc, objv) /* Handle an error thrown by a tcl vfs implementation */ static void VfsInternalError(Tcl_Interp* interp) { - Tcl_MutexLock(&internalErrorMutex); - if (internalErrorScript != NULL) { - Tcl_EvalObjEx(interp, internalErrorScript, - TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT); + if (interp != NULL) { + Tcl_MutexLock(&internalErrorMutex); + if (internalErrorScript != NULL) { + Tcl_EvalObjEx(interp, internalErrorScript, + TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT); + } + Tcl_MutexUnlock(&internalErrorMutex); } - Tcl_MutexUnlock(&internalErrorMutex); } /* Return fully normalized path owned by the caller */ @@ -1344,7 +1346,7 @@ VfsOpenFileChannel(cmdInterp, pathPtr, mode, permissions) Tcl_ResetResult(cmdInterp); Tcl_AppendResult(cmdInterp, "couldn't open \"", Tcl_GetString(pathPtr), "\": ", - Tcl_PosixError(interp), (char *) NULL); + Tcl_PosixError(cmdInterp), (char *) NULL); } else { Tcl_Obj* error = Tcl_GetObjResult(interp); /* @@ -1353,6 +1355,11 @@ VfsOpenFileChannel(cmdInterp, pathPtr, mode, permissions) */ Tcl_SetObjResult(cmdInterp, Tcl_DuplicateObj(error)); } + } else { + /* Report any error, since otherwise it is lost */ + if (returnVal != -1) { + VfsInternalError(interp); + } } if (interp == cmdInterp) { /* @@ -1663,6 +1670,11 @@ VfsFileAttrsGet(cmdInterp, index, pathPtr, objPtrRef) Tcl_SetObjResult(cmdInterp, *objPtrRef); *objPtrRef = NULL; } + } else { + Tcl_ResetResult(cmdInterp); + Tcl_AppendResult(cmdInterp, "couldn't read attributes for \"", + Tcl_GetString(pathPtr), "\": ", + Tcl_PosixError(cmdInterp), (char *) NULL); } return returnVal; @@ -1699,7 +1711,12 @@ VfsFileAttrsSet(cmdInterp, index, pathPtr, objPtr) Tcl_RestoreResult(interp, &savedResult); Tcl_DecrRefCount(mountCmd); - if (errorPtr != NULL) { + if (returnVal == -1) { + Tcl_ResetResult(cmdInterp); + Tcl_AppendResult(cmdInterp, "couldn't set attributes for \"", + Tcl_GetString(pathPtr), "\": ", + Tcl_PosixError(cmdInterp), (char *) NULL); + } else if (errorPtr != NULL) { /* * Leave error message in correct interp, errorPtr was * duplicated above, in case of threading issues.