Annotation For xvfs-core.c

Lines of xvfs-core.c from check-in acfc5037c6 that are changed by the sequence of edits moving toward check-in 3e44e1def1:

                         1: #include <xvfs-core.h>
                         2: #include <string.h>
                         3: #include <tcl.h>
                         4: 
                         5: #define XVFS_ROOT_MOUNTPOINT "//xvfs:/"
                         6: 
                         7: struct xvfs_tclfs_instance_info {
                         8: 	struct Xvfs_FSInfo *fsInfo;
                         9: 	Tcl_Obj            *mountpoint;
                        10: };
                        11: 
                        12: /*
                        13:  * Internal Core Utilities
                        14:  */
                        15: static const char *xvfs_relativePath(Tcl_Obj *path, struct xvfs_tclfs_instance_info *info) {
                        16: 	const char *pathStr, *rootStr;
                        17: 	int pathLen, rootLen;
                        18: 	
                        19: 	pathStr = Tcl_GetStringFromObj(path, &pathLen);
                        20: 	rootStr = Tcl_GetStringFromObj(info->mountpoint, &rootLen);
                        21: 	
                        22: 	if (pathLen < rootLen) {
                        23: 		return(NULL);
                        24: 	}
                        25: 	
                        26: 	if (memcmp(pathStr, rootStr, rootLen) != 0) {
                        27: 		return(NULL);
                        28: 	}
                        29: 	
                        30: 	if (pathLen == rootLen) {
                        31: 		return("");
                        32: 	}
                        33: 
                        34: 	/* XXX:TODO: Should this use the native OS path separator ? */
                        35: 	if (pathStr[rootLen] != '/') {
                        36: 		return(NULL);
                        37: 	}
                        38: 	
                        39: 	return(pathStr + rootLen + 1);
                        40: }
                        41: 
                        42: /*
                        43:  * Internal Tcl_Filesystem functions, with the appropriate instance info
                        44:  */
                        45: static int xvfs_tclfs_pathInFilesystem(Tcl_Obj *path, ClientData *dataPtr, struct xvfs_tclfs_instance_info *instanceInfo) {
                        46: 	const char *relativePath;
                        47: 	
                        48: 	relativePath = xvfs_relativePath(path, instanceInfo);
                        49: 	if (!relativePath) {
                        50: 		return(-1);
                        51: 	}
                        52: 	
                        53: 	return(TCL_OK);
                        54: }
                        55: 
                        56: static int xvfs_tclfs_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf, struct xvfs_tclfs_instance_info *instanceInfo) {
                        57: 	const char *pathStr;
                        58: 	int retval;
                        59: 
                        60: 	pathStr = xvfs_relativePath(path, instanceInfo);
                        61: 	
                        62: 	retval = instanceInfo->fsInfo->getInfoProc(pathStr, statBuf);
                        63: 	
                        64: 	return(retval);
                        65: }
                        66: 
                        67: static Tcl_Obj *xvfs_tclfs_listVolumes(struct xvfs_tclfs_instance_info *instanceInfo) {
                        68: 	return(NULL);
                        69: }
                        70: 
                        71: static Tcl_Channel xvfs_tclfs_openFileChannel(Tcl_Interp *interp, Tcl_Obj *path, int mode, int permissions, struct xvfs_tclfs_instance_info *instanceInfo) {
                        72: 	const char *pathStr;
                        73: 
                        74: 	pathStr = xvfs_relativePath(path, instanceInfo);
                        75: fprintf(stderr, "Called open(%s)!\n", pathStr);
                        76: 	
                        77: 	return(NULL);
                        78: }
                        79: 
acfc5037c6 2019-05-02   80: #if XVFS_MODE == standalone
                        81: /*
                        82:  * Tcl_Filesystem handlers for the standalone implementation
                        83:  */
                        84: static struct xvfs_tclfs_instance_info xvfs_tclfs_standalone_info;
                        85: static int xvfs_tclfs_standalone_pathInFilesystem(Tcl_Obj *path, ClientData *dataPtr) {
                        86: 	return(xvfs_tclfs_pathInFilesystem(path, dataPtr, &xvfs_tclfs_standalone_info));
                        87: }
                        88: 
                        89: static int xvfs_tclfs_standalone_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf) {
                        90: 	return(xvfs_tclfs_stat(path, statBuf, &xvfs_tclfs_standalone_info));
                        91: }
                        92: 
                        93: static Tcl_Obj *xvfs_tclfs_standalone_listVolumes(void) {
                        94: 	return(xvfs_tclfs_listVolumes(&xvfs_tclfs_standalone_info));
                        95: }
                        96: 
                        97: static Tcl_Channel xvfs_tclfs_standalone_openFileChannel(Tcl_Interp *interp, Tcl_Obj *path, int mode, int permissions) {
                        98: 	return(xvfs_tclfs_openFileChannel(interp, path, mode, permissions, &xvfs_tclfs_standalone_info));
                        99: }
                       100: 
                       101: /*
                       102:  * There are three (3) modes of operation for Xvfs_Register:
                       103:  *    1. standalone -- We register our own Tcl_Filesystem
                       104:  *                     and handle requests under `//xvfs:/<fsName>`
                       105:  *    2. client -- A single Tcl_Filesystem is registered for the
                       106:  *                 interp to handle requests under `//xvfs:/` which
                       107:  *                 then dispatches to the appropriate registered
                       108:  *                 handler
                       109:  *    3. flexible -- Attempts to find a core Xvfs instance for the
                       110:  *                   process at runtime, if found do #2, otherwise
                       111:  *                   fallback to #1
                       112:  *
                       113:  */
                       114: int xvfs_standalone_register(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo) {
                       115: 	Tcl_Filesystem *xvfs_tclfs_Info;
                       116: 	int tcl_ret;
                       117: 	static int registered = 0;
                       118: 	
                       119: 	/*
                       120: 	 * Ensure this instance is not already registered
                       121: 	 */
                       122: 	if (registered) {
                       123: 		return(TCL_OK);
                       124: 	}
                       125: 	registered = 1;
                       126: 
                       127: 	/*
                       128: 	 * In standalone mode, we only support the same protocol we are
                       129: 	 * compiling for.
                       130: 	 */
                       131: 	if (fsInfo->protocolVersion != XVFS_PROTOCOL_VERSION) {
                       132: 		if (interp) {
                       133: 			Tcl_SetResult(interp, "Protocol mismatch", NULL);
                       134: 		}
                       135: 		return(TCL_ERROR);
                       136: 	}
                       137: 	
                       138: 	xvfs_tclfs_Info = (Tcl_Filesystem *) Tcl_AttemptAlloc(sizeof(*xvfs_tclfs_Info));
                       139: 	if (!xvfs_tclfs_Info) {
                       140: 		if (interp) {
                       141: 			Tcl_SetResult(interp, "Unable to allocate Tcl_Filesystem object", NULL);
                       142: 		}
                       143: 		return(TCL_ERROR);
                       144: 	}
                       145: 	
acfc5037c6 2019-05-02  146: 	xvfs_tclfs_Info->typeName                   = strdup("xvfs");
                       147: 	xvfs_tclfs_Info->structureLength            = sizeof(*xvfs_tclfs_Info);
                       148: 	xvfs_tclfs_Info->version                    = TCL_FILESYSTEM_VERSION_1;
                       149: 	xvfs_tclfs_Info->pathInFilesystemProc       = xvfs_tclfs_standalone_pathInFilesystem;
                       150: 	xvfs_tclfs_Info->dupInternalRepProc         = NULL;
                       151: 	xvfs_tclfs_Info->freeInternalRepProc        = NULL;
                       152: 	xvfs_tclfs_Info->internalToNormalizedProc   = NULL;
                       153: 	xvfs_tclfs_Info->createInternalRepProc      = NULL;
                       154: 	xvfs_tclfs_Info->normalizePathProc          = NULL;
                       155: 	xvfs_tclfs_Info->filesystemPathTypeProc     = NULL;
                       156: 	xvfs_tclfs_Info->filesystemSeparatorProc    = NULL;
                       157: 	xvfs_tclfs_Info->statProc                   = xvfs_tclfs_standalone_stat;
                       158: 	xvfs_tclfs_Info->accessProc                 = NULL;
                       159: 	xvfs_tclfs_Info->openFileChannelProc        = xvfs_tclfs_standalone_openFileChannel;
                       160: 	xvfs_tclfs_Info->matchInDirectoryProc       = NULL;
                       161: 	xvfs_tclfs_Info->utimeProc                  = NULL;
                       162: 	xvfs_tclfs_Info->linkProc                   = NULL;
                       163: 	xvfs_tclfs_Info->listVolumesProc            = xvfs_tclfs_standalone_listVolumes;
                       164: 	xvfs_tclfs_Info->fileAttrStringsProc        = NULL;
                       165: 	xvfs_tclfs_Info->fileAttrsGetProc           = NULL;
                       166: 	xvfs_tclfs_Info->fileAttrsSetProc           = NULL;
                       167: 	xvfs_tclfs_Info->createDirectoryProc        = NULL;
                       168: 	xvfs_tclfs_Info->removeDirectoryProc        = NULL;
                       169: 	xvfs_tclfs_Info->deleteFileProc             = NULL;
                       170: 	xvfs_tclfs_Info->copyFileProc               = NULL;
                       171: 	xvfs_tclfs_Info->renameFileProc             = NULL;
                       172: 	xvfs_tclfs_Info->copyDirectoryProc          = NULL;
                       173: 	xvfs_tclfs_Info->lstatProc                  = NULL;
                       174: 	xvfs_tclfs_Info->loadFileProc               = NULL;
                       175: 	xvfs_tclfs_Info->getCwdProc                 = NULL;
                       176: 	xvfs_tclfs_Info->chdirProc                  = NULL;
                       177: 
                       178: 	xvfs_tclfs_standalone_info.fsInfo = fsInfo;
                       179: 	xvfs_tclfs_standalone_info.mountpoint = Tcl_NewObj();
                       180: 	Tcl_AppendStringsToObj(xvfs_tclfs_standalone_info.mountpoint, XVFS_ROOT_MOUNTPOINT, fsInfo->name, NULL);
                       181: 	
                       182: 	tcl_ret = Tcl_FSRegister(NULL, xvfs_tclfs_Info);
                       183: 	if (tcl_ret != TCL_OK) {
                       184: 		if (interp) {
                       185: 			Tcl_SetResult(interp, "Tcl_FSRegister() failed", NULL);
                       186: 		}
                       187: 		
                       188: 		return(tcl_ret);
                       189: 	}
                       190: 	
                       191: 	return(TCL_OK);
                       192: }
acfc5037c6 2019-05-02  193: #else
                       194: int Xvfs_Register(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo) {
                       195: 	return(TCL_ERROR);
                       196: }
                       197: #endif