Index: example/main.tcl ================================================================== --- example/main.tcl +++ example/main.tcl @@ -71,15 +71,23 @@ } -cleanup { close $fd unset fd } -result "" -tcltest::test xvfs-basic-open-write "Xvfs Open For Writing Test" -setup { +tcltest::test xvfs-basic-open-neg "Xvfs Open Non-Existant File Test" -body { + unset -nocomplain fd + set fd [open $rootDir/does-not-exist] +} -cleanup { + if {[info exists fd]} { + close $fd + unset fd + } +} -returnCodes error -result "no such file or directory" + +tcltest::test xvfs-basic-open-write "Xvfs Open For Writing Test" -body { unset -nocomplain fd -} -body { set fd [open $rootDir/new-file w] - close $fd } -cleanup { if {[info exists fd]} { close $fd unset fd } @@ -86,10 +94,21 @@ catch { file delete $rootDir/new-file } } -match glob -returnCodes error -result "*read*only file*system*" +tcltest::test xvfs-basic-open-directory "Xvfs Open Directory Test" -body { + unset -nocomplain fd + set fd [open $rootDir/lib] + set fd +} -cleanup { + if {[info exists fd]} { + close $fd + unset fd + } +} -match glob -returnCodes error -result "*illegal operation on a directory" + tcltest::test xvfs-basic-two-files "Xvfs Multiple Open Files Test" -setup { set fd1 [open $testFile] set fd2 [open $testFile] } -body { set data1 [read $fd1] @@ -188,10 +207,16 @@ file stat $testFile fileInfo set fileInfo(type) } -cleanup { unset -nocomplain fileInfo } -result file + +tcltest::test xvfs-stat-basic-file-neg "Xvfs stat Basic File Negative Test" -body { + file stat $rootDir/does-not-exist fileInfo +} -cleanup { + unset -nocomplain fileInfo +} -match glob -returnCodes error -result "*no such file or directory" tcltest::test xvfs-stat-basic-dir "Xvfs stat Basic Directory Test" -body { file stat $rootDir/lib fileInfo set fileInfo(type) } -cleanup { Index: xvfs-core.c ================================================================== --- xvfs-core.c +++ xvfs-core.c @@ -169,10 +169,21 @@ return("Internal error"); default: return("Unknown error"); } } + +static void xvfs_setresults_error(Tcl_Interp *interp, int xvfs_error) { + if (!interp) { + return; + } + + Tcl_SetErrno(xvfs_errorToErrno(xvfs_error)); + Tcl_SetResult(interp, (char *) xvfs_perror(xvfs_error), NULL); + + return; +} /* * Xvfs Memory Channel */ struct xvfs_tclfs_channel_id { @@ -189,11 +200,11 @@ Tcl_Event tcl; struct xvfs_tclfs_channel_id *channelInstanceData; }; static Tcl_ChannelType xvfs_tclfs_channelType; -static Tcl_Channel xvfs_tclfs_openChannel(Tcl_Obj *path, struct xvfs_tclfs_instance_info *instanceInfo) { +static Tcl_Channel xvfs_tclfs_openChannel(Tcl_Interp *interp, Tcl_Obj *path, struct xvfs_tclfs_instance_info *instanceInfo) { struct xvfs_tclfs_channel_id *channelInstanceData; Tcl_Channel channel; Tcl_StatBuf fileInfo; Tcl_Obj *channelName; int statRet; @@ -202,10 +213,21 @@ XVFS_DEBUG_PRINTF("Opening file \"%s\" ...", Tcl_GetString(path)); statRet = instanceInfo->fsInfo->getStatProc(Tcl_GetString(path), &fileInfo); if (statRet < 0) { XVFS_DEBUG_PRINTF("... failed: %s", xvfs_perror(statRet)); + + xvfs_setresults_error(interp, XVFS_RV_ERR_ENOENT); + + XVFS_DEBUG_LEAVE; + return(NULL); + } + + if (fileInfo.st_mode & 040000) { + XVFS_DEBUG_PUTS("... failed (cannot open directories)"); + + xvfs_setresults_error(interp, XVFS_RV_ERR_EISDIR); XVFS_DEBUG_LEAVE; return(NULL); } @@ -575,14 +597,11 @@ XVFS_DEBUG_PRINTF("Asked to open(\"%s\", %x)...", Tcl_GetString(path), mode); if (mode & O_WRONLY) { XVFS_DEBUG_PUTS("... failed (asked to open for writing)"); - if (interp) { - Tcl_SetErrno(xvfs_errorToErrno(XVFS_RV_ERR_EROFS)); - Tcl_SetResult(interp, (char *) Tcl_PosixError(interp), NULL); - } + xvfs_setresults_error(interp, XVFS_RV_ERR_EROFS); XVFS_DEBUG_LEAVE; return(NULL); } @@ -594,11 +613,11 @@ Tcl_DecrRefCount(path); XVFS_DEBUG_PUTS("... done, passing off to channel handler"); - retval = xvfs_tclfs_openChannel(pathRel, instanceInfo); + retval = xvfs_tclfs_openChannel(interp, pathRel, instanceInfo); XVFS_DEBUG_LEAVE; return(retval); } @@ -732,13 +751,11 @@ if (!pathStr) { XVFS_DEBUG_PUTS("... error (not in our VFS)"); Tcl_DecrRefCount(path); - if (interp) { - Tcl_SetResult(interp, (char *) xvfs_perror(XVFS_RV_ERR_ENOENT), NULL); - } + xvfs_setresults_error(interp, XVFS_RV_ERR_ENOENT); XVFS_DEBUG_LEAVE; return(TCL_OK); } @@ -747,13 +764,11 @@ if (childrenCount < 0) { XVFS_DEBUG_PRINTF("... error: %s", xvfs_perror(childrenCount)); Tcl_DecrRefCount(path); - if (interp) { - Tcl_SetResult(interp, (char *) xvfs_perror(childrenCount), NULL); - } + xvfs_setresults_error(interp, childrenCount); XVFS_DEBUG_LEAVE; return(TCL_ERROR); }