Index: xvfs-core.c ================================================================== --- xvfs-core.c +++ xvfs-core.c @@ -47,10 +47,31 @@ return(NULL); } return(pathStr + rootLen + 1); } + +static const char *xvfs_perror(int xvfs_error) { + if (xvfs_error >= 0) { + return("Not an error"); + } + + switch (xvfs_error) { + case XVFS_RV_ERR_ENOENT: + return("No such file or directory"); + case XVFS_RV_ERR_EINVAL: + return("Invalid argument"); + case XVFS_RV_ERR_EISDIR: + return("Is a directory"); + case XVFS_RV_ERR_ENOTDIR: + return("Not a directory"); + case XVFS_RV_ERR_EFAULT: + return("Bad address"); + default: + return("Unknown error"); + } +} /* * Internal Tcl_Filesystem functions, with the appropriate instance info */ static int xvfs_tclfs_pathInFilesystem(Tcl_Obj *path, ClientData *dataPtr, struct xvfs_tclfs_instance_info *instanceInfo) { @@ -69,10 +90,13 @@ int retval; pathStr = xvfs_relativePath(path, instanceInfo); retval = instanceInfo->fsInfo->getStatProc(pathStr, statBuf); + if (retval < 0) { + retval = -1; + } return(retval); } static Tcl_Obj *xvfs_tclfs_listVolumes(struct xvfs_tclfs_instance_info *instanceInfo) { @@ -79,12 +103,15 @@ return(NULL); } static Tcl_Channel xvfs_tclfs_openFileChannel(Tcl_Interp *interp, Tcl_Obj *path, int mode, int permissions, struct xvfs_tclfs_instance_info *instanceInfo) { const char *pathStr; + Tcl_WideInt length; + const char *data; pathStr = xvfs_relativePath(path, instanceInfo); + /* * XXX:TODO: Do something to create the Tcl_Channel we * need to return here */ Index: xvfs-core.h ================================================================== --- xvfs-core.h +++ xvfs-core.h @@ -7,18 +7,33 @@ typedef const char **(*xvfs_proc_getChildren_t)(const char *path, Tcl_WideInt *count); typedef const unsigned char *(*xvfs_proc_getData_t)(const char *path, Tcl_WideInt start, Tcl_WideInt *length); typedef int (*xvfs_proc_getStat_t)(const char *path, Tcl_StatBuf *statBuf); +/* + * Interface for the filesystem to fill out before registering. + * The protocolVersion is provided first so that if this + * needs to change over time it can be appropriately handled. + */ struct Xvfs_FSInfo { int protocolVersion; const char *name; xvfs_proc_getChildren_t getChildrenProc; xvfs_proc_getData_t getDataProc; xvfs_proc_getStat_t getStatProc; }; +/* + * Error codes for various calls. This is part of the ABI and must + * not be changed. + */ +#define XVFS_RV_ERR_ENOENT (-8192) +#define XVFS_RV_ERR_EINVAL (-8193) +#define XVFS_RV_ERR_EISDIR (-8194) +#define XVFS_RV_ERR_ENOTDIR (-8195) +#define XVFS_RV_ERR_EFAULT (-8196) + #define XVFS_REGISTER_INTERFACE(name) int name(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo); #if defined(XVFS_MODE_STANDALONE) /* * In standalone mode, we just redefine calls to Index: xvfs.c.rvt ================================================================== --- xvfs.c.rvt +++ xvfs.c.rvt @@ -36,10 +36,12 @@ if (path == NULL) { return(XVFS_NAME_LOOKUP_ERROR); } +printf("Looking for %s\n", path); + pathLen = strlen(path); pathHash = Tcl_ZlibAdler32(0, (const unsigned char *) path, pathLen); switch (pathHash) { _nameToIndex(path); if (inode == XVFS_NAME_LOOKUP_ERROR) { + *count = XVFS_RV_ERR_ENOENT; return(NULL); } fileInfo = &xvfs__data[inode]; /* * Ensure this is a directory */ if (fileInfo->type != XVFS_FILE_TYPE_DIR) { + *count = XVFS_RV_ERR_ENOTDIR; return(NULL); } *count = fileInfo->size; return(fileInfo->data.dirChildren); @@ -104,44 +108,48 @@ long inode; /* * Validate input parameters */ + if (length == NULL) { + return(NULL); + } + if (start < 0) { - return(NULL); - } - - if (length == NULL) { + *length = XVFS_RV_ERR_EINVAL; return(NULL); } if (*length < 0) { + *length = XVFS_RV_ERR_EINVAL; return(NULL); } /* * Get the inode from the lookup function */ inode = xvfs__nameToIndex(path); if (inode == XVFS_NAME_LOOKUP_ERROR) { + *length = XVFS_RV_ERR_ENOENT; return(NULL); } fileInfo = &xvfs__data[inode]; /* * Ensure this is a file that can be read */ if (fileInfo->type != XVFS_FILE_TYPE_REG) { + *length = XVFS_RV_ERR_EISDIR; return(NULL); } /* * Validate the length */ if (start > fileInfo->size) { - *length = -1; + *length = XVFS_RV_ERR_EFAULT; return(NULL); } if (*length == 0) { resultLength = fileInfo->size - start; @@ -162,19 +170,19 @@ /* * Validate input parameters */ if (!statBuf) { - return(-1); + return(XVFS_RV_ERR_EINVAL); } /* * Get the inode from the lookup function */ inode = xvfs__nameToIndex(path); if (inode == XVFS_NAME_LOOKUP_ERROR) { - return(-1); + return(XVFS_RV_ERR_ENOENT); } fileInfo = &xvfs__data[inode]; statBuf->st_dev = 0;