Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -74,11 +74,13 @@ echo 'if {[catch { eval $$::env(XVFS_TEST_LOAD_COMMANDS); source $(XVFS_ROOT_MOUNTPOINT)example/main.tcl }]} { puts stderr $$::errorInfo; exit 1 }; exit 0' > __test__.tcl @export XVFS_ROOT_MOUNTPOINT; export XVFS_TEST_LOAD_COMMANDS; for XVFS_TEST_LOAD_COMMANDS in \ 'load ./example-standalone$(LIB_SUFFIX) Xvfs_example' \ 'load -global ./xvfs$(LIB_SUFFIX); load ./example-client$(LIB_SUFFIX) Xvfs_example' \ 'load ./xvfs$(LIB_SUFFIX); load ./example-flexible$(LIB_SUFFIX) Xvfs_example' \ - 'load ./example-flexible$(LIB_SUFFIX) Xvfs_example'; do \ + 'load ./example-flexible$(LIB_SUFFIX) Xvfs_example' \ + 'load ./xvfs$(LIB_SUFFIX); load ./example-standalone$(LIB_SUFFIX) Xvfs_example' \ + 'load ./example-standalone$(LIB_SUFFIX) Xvfs_example; load ./xvfs$(LIB_SUFFIX)'; do \ echo "[$${XVFS_TEST_LOAD_COMMANDS}] $(GDB) $(TCLSH) __test__.tcl $(TCL_TEST_ARGS)"; \ $(GDB) $(TCLSH) __test__.tcl $(TCL_TEST_ARGS) || exit 1; \ done rm -f __test__.tcl Index: xvfs-core.c ================================================================== --- xvfs-core.c +++ xvfs-core.c @@ -25,10 +25,12 @@ #define XVFS_INTERNAL_SERVER_MAGIC "\xD4\xF3\x05\x96\x25\xCF\xAF\xFE" #define XVFS_INTERNAL_SERVER_MAGIC_LEN 8 struct xvfs_tclfs_server_info { char magic[XVFS_INTERNAL_SERVER_MAGIC_LEN]; + int protocolVersion; + const char *rootMountpoint; int (*registerProc)(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo); }; #endif /* XVFS_MODE_FLEXIBLE || XVFS_MODE_SERVER */ #if defined(XVFS_MODE_SERVER) || defined(XVFS_MODE_STANDALONE) || defined(XVFS_MODE_FLEXIBLE) @@ -980,12 +982,29 @@ /* * XXX:TODO: What is the chance that the handler for //xvfs:/ hold * client data smaller than XVFS_INTERNAL_SERVER_MAGIC_LEN ? */ if (memcmp(fsHandlerData->magic, XVFS_INTERNAL_SERVER_MAGIC, sizeof(fsHandlerData->magic)) == 0) { - XVFS_DEBUG_PUTS("Found a server handler"); - xvfs_register = fsHandlerData->registerProc; + /* + * Refuse to talk to the in-core implementation if it is a lower + * version. + */ + XVFS_DEBUG_PUTS("Found a server handler, checking for compatible version"); + if (fsHandlerData->protocolVersion >= XVFS_PROTOCOL_VERSION) { + XVFS_DEBUG_PUTS("Found a server handler with a compatible version, checking for compatible root"); + if (strcmp(XVFS_ROOT_MOUNTPOINT, fsHandlerData->rootMountpoint) == 0) { + XVFS_DEBUG_PUTS("Found a server handler with a compatible version and checking for compatible root"); + + xvfs_register = fsHandlerData->registerProc; + } + } + } + + if (xvfs_register == &xvfs_standalone_register) { + XVFS_DEBUG_PUTS("Using xvfs_standalone_register"); + } else { + XVFS_DEBUG_PUTS("Using Xvfs_Register from Xvfs Server Core"); } XVFS_DEBUG_LEAVE; return(xvfs_register(interp, fsInfo)); @@ -995,11 +1014,11 @@ #if defined(XVFS_MODE_SERVER) static Tcl_Filesystem xvfs_tclfs_dispatch_fs; static Tcl_HashTable xvfs_tclfs_dispatch_map; static struct xvfs_tclfs_server_info xvfs_tclfs_dispatch_fsdata; -static int xvfs_tclfs_dispatch_pathInFS(Tcl_Obj *path, ClientData *dataPtr) { +static int xvfs_tclfs_dispatch_pathInXVFS(Tcl_Obj *path) { const char *pathStr, *rootStr; int pathLen, rootLen; XVFS_DEBUG_ENTER; @@ -1045,11 +1064,11 @@ XVFS_DEBUG_ENTER; path = xvfs_absolutePath(path); - if (xvfs_tclfs_dispatch_pathInFS(path, NULL) != TCL_OK) { + if (xvfs_tclfs_dispatch_pathInXVFS(path) != TCL_OK) { Tcl_DecrRefCount(path); XVFS_DEBUG_LEAVE; return(NULL); @@ -1093,10 +1112,21 @@ * a warning about it not being used. */ xvfs_tclfs_pathInFilesystem(NULL, NULL, NULL); return(NULL); } + +static int xvfs_tclfs_dispatch_pathInFS(Tcl_Obj *path, ClientData *dataPtr) { + struct xvfs_tclfs_instance_info *instanceInfo; + + instanceInfo = xvfs_tclfs_dispatch_pathToInfo(path); + if (!instanceInfo) { + return(-1); + } + + return(TCL_OK); +} static int xvfs_tclfs_dispatch_stat(Tcl_Obj *path, Tcl_StatBuf *statBuf) { struct xvfs_tclfs_instance_info *instanceInfo; instanceInfo = xvfs_tclfs_dispatch_pathToInfo(path); @@ -1194,11 +1224,13 @@ xvfs_tclfs_dispatch_fs.loadFileProc = NULL; xvfs_tclfs_dispatch_fs.getCwdProc = NULL; xvfs_tclfs_dispatch_fs.chdirProc = NULL; memcpy(xvfs_tclfs_dispatch_fsdata.magic, XVFS_INTERNAL_SERVER_MAGIC, XVFS_INTERNAL_SERVER_MAGIC_LEN); - xvfs_tclfs_dispatch_fsdata.registerProc = Xvfs_Register; + xvfs_tclfs_dispatch_fsdata.registerProc = Xvfs_Register; + xvfs_tclfs_dispatch_fsdata.protocolVersion = XVFS_PROTOCOL_VERSION; + xvfs_tclfs_dispatch_fsdata.rootMountpoint = XVFS_ROOT_MOUNTPOINT; tclRet = Tcl_FSRegister((ClientData) &xvfs_tclfs_dispatch_fsdata, &xvfs_tclfs_dispatch_fs); if (tclRet != TCL_OK) { if (interp) { Tcl_SetResult(interp, "Tcl_FSRegister() failed", NULL);