Index: example/main.tcl ================================================================== --- example/main.tcl +++ example/main.tcl @@ -104,7 +104,20 @@ set check [glob_verify -type d *] if {[llength $check] != 1} { error "EXPECTED 1, GOT [llength $check] ($check)" } + +set check [glob_verify -type d lib/*] +if {[llength $check] != 1} { + error "EXPECTED 1, GOT [llength $check] ($check)" +} + +cd $dir +cd lib +glob * + + +lappend auto_path ${dir}/lib +package require hello puts "ALL TESTS PASSED" Index: xvfs-core.c ================================================================== --- xvfs-core.c +++ xvfs-core.c @@ -29,12 +29,16 @@ static const char *xvfs_relativePath(Tcl_Obj *path, struct xvfs_tclfs_instance_info *info) { const char *pathStr, *rootStr; const char *pathFinal; int pathLen, rootLen; - pathStr = Tcl_GetStringFromObj(path, &pathLen); rootStr = Tcl_GetStringFromObj(info->mountpoint, &rootLen); + pathStr = Tcl_GetStringFromObj(path, &pathLen); + if (pathStr[0] != '/') { + path = Tcl_ObjPrintf("%s/%s", Tcl_GetString(Tcl_FSGetCwd(NULL)), pathStr); + pathStr = Tcl_GetStringFromObj(path, &pathLen); + } if (pathLen < rootLen) { return(NULL); } @@ -395,10 +399,35 @@ retval = -1; } return(retval); } + +static int xvfs_tclfs_access(Tcl_Obj *path, int mode, struct xvfs_tclfs_instance_info *instanceInfo) { + const char *pathStr; + Tcl_StatBuf fileInfo; + int statRetVal; + + pathStr = xvfs_relativePath(path, instanceInfo); + + if (mode & W_OK) { + return(-1); + } + + statRetVal = instanceInfo->fsInfo->getStatProc(pathStr, &fileInfo); + if (statRetVal < 0) { + return(-1); + } + + if (mode & X_OK) { + if (!(fileInfo.st_mode & 040000)) { + return(-1); + } + } + + return(0); +} static Tcl_Obj *xvfs_tclfs_listVolumes(struct xvfs_tclfs_instance_info *instanceInfo) { return(NULL); } @@ -427,13 +456,19 @@ if (!types) { return(1); } if (types->perm != TCL_GLOB_PERM_RONLY) { - if (types->perm & (TCL_GLOB_PERM_W | TCL_GLOB_PERM_X | TCL_GLOB_PERM_HIDDEN)) { + if (types->perm & (TCL_GLOB_PERM_W | TCL_GLOB_PERM_HIDDEN)) { return(0); } + + if ((types->perm & TCL_GLOB_PERM_X) == TCL_GLOB_PERM_X) { + if (!(fileInfo.st_mode & 040000)) { + return(0); + } + } } if (types->type & (TCL_GLOB_TYPE_BLOCK | TCL_GLOB_TYPE_CHAR | TCL_GLOB_TYPE_PIPE | TCL_GLOB_TYPE_SOCK | TCL_GLOB_TYPE_LINK)) { return(0); } @@ -537,10 +572,14 @@ } static int xvfs_tclfs_standalone_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf) { return(xvfs_tclfs_stat(path, statBuf, &xvfs_tclfs_standalone_info)); } + +static int xvfs_tclfs_standalone_access(Tcl_Obj *path, int mode) { + return(xvfs_tclfs_access(path, mode, &xvfs_tclfs_standalone_info)); +} static Tcl_Obj *xvfs_tclfs_standalone_listVolumes(void) { return(xvfs_tclfs_listVolumes(&xvfs_tclfs_standalone_info)); } @@ -599,11 +638,11 @@ xvfs_tclfs_standalone_fs.createInternalRepProc = NULL; xvfs_tclfs_standalone_fs.normalizePathProc = NULL; xvfs_tclfs_standalone_fs.filesystemPathTypeProc = NULL; xvfs_tclfs_standalone_fs.filesystemSeparatorProc = NULL; xvfs_tclfs_standalone_fs.statProc = xvfs_tclfs_standalone_stat; - xvfs_tclfs_standalone_fs.accessProc = NULL; + xvfs_tclfs_standalone_fs.accessProc = xvfs_tclfs_standalone_access; xvfs_tclfs_standalone_fs.openFileChannelProc = xvfs_tclfs_standalone_openFileChannel; xvfs_tclfs_standalone_fs.matchInDirectoryProc = xvfs_tclfs_standalone_matchInDir; xvfs_tclfs_standalone_fs.utimeProc = NULL; xvfs_tclfs_standalone_fs.linkProc = NULL; xvfs_tclfs_standalone_fs.listVolumesProc = xvfs_tclfs_standalone_listVolumes;