Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -1,9 +1,9 @@ CPPFLAGS := -I. -DUSE_TCL_STUBS=1 -DXVFS_MODE_FLEXIBLE CFLAGS := -fPIC -g3 -ggdb3 -Wall LDFLAGS := -LIBS := -ltclstub8.6 -ldl +LIBS := -ltclstub8.6 all: example.so example.c: $(shell find example -type f) $(shell find lib -type f) xvfs.c.rvt xvfs-create Makefile ./xvfs-create --directory example --name example > example.c.new Index: xvfs-core.c ================================================================== --- xvfs-core.c +++ xvfs-core.c @@ -183,28 +183,60 @@ } return(TCL_OK); } #endif + +#if defined(XVFS_MODE_FLEXIBLE) || defined(XVFS_MODE_SERVER) +struct xvfs_tclfs_server_info { + char magic[XVFS_PROTOCOL_SERVER_MAGIC_LEN]; + int (*registerProc)(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo); +}; +#endif #if defined(XVFS_MODE_FLEXIBLE) -#include int xvfs_flexible_register(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo) { - int (*xvfs_register)(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo) = NULL; + ClientData fsHandlerDataRaw; + struct xvfs_tclfs_server_info *fsHandlerData; + const Tcl_Filesystem *fsHandler; + int (*xvfs_register)(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo); + Tcl_Obj *rootPathObj; + + xvfs_register = &xvfs_standalone_register; + + rootPathObj = Tcl_NewStringObj(XVFS_ROOT_MOUNTPOINT, -1); + if (!rootPathObj) { + return(xvfs_register(interp, fsInfo)); + } + + Tcl_IncrRefCount(rootPathObj); + fsHandler = Tcl_FSGetFileSystemForPath(rootPathObj); + Tcl_DecrRefCount(rootPathObj); + + if (!fsHandler) { + return(xvfs_register(interp, fsInfo)); + } + + fsHandlerDataRaw = Tcl_FSData(fsHandler); + if (!fsHandlerDataRaw) { + return(xvfs_register(interp, fsInfo)); + } + + fsHandlerData = (struct xvfs_tclfs_server_info *) fsHandlerDataRaw; /* - * XXX:TODO: Find some way to use Tcl_FindSymbol() to do this + * XXX:TODO: What is the chance that the handler for //xvfs:/ hold + * client data smaller than XVFS_PROTOCOL_SERVER_MAGIC_LEN ? */ - xvfs_register = dlsym(NULL, "Xvfs_Register"); - if (!xvfs_register) { - xvfs_register = &xvfs_standalone_register; + if (memcmp(fsHandlerData->magic, XVFS_PROTOCOL_SERVER_MAGIC, sizeof(fsHandlerData->magic)) == 0) { + xvfs_register = fsHandlerData->registerProc; } - + return(xvfs_register(interp, fsInfo)); } #endif #if defined(XVFS_MODE_SERVER) int Xvfs_Register(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo) { return(TCL_ERROR); } #endif Index: xvfs-core.h ================================================================== --- xvfs-core.h +++ xvfs-core.h @@ -2,10 +2,12 @@ #define XVFS_CORE_H_1B4B28D60EBAA11D5FF85642FA7CA22C29E8E817 1 #include #define XVFS_PROTOCOL_VERSION 1 +#define XVFS_PROTOCOL_SERVER_MAGIC "\xD4\xF3\x05\x96\x25\xCF\xAF\xFE" +#define XVFS_PROTOCOL_SERVER_MAGIC_LEN 8 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);