Tcl pathInFilesystemProc 获取当前文件系统

Tcl pathInFilesystemProc get current filesystem

使用 tcl 创建 vfs 时 api 如何在 Tcl_Filesystem.pathInFilesystemProc

中获取当前文件系统

我的代码看起来像这样:

typedef struct {
    FILE* dbFile;
    /*...*/

} FSBackend;

void createFS(const char* dbFile)
{

    FSBackend* fsback = (FSBackend*)malloc(sizeof(FSBackend));
    initDb(fsback,dbFile);

    Tcl_Filesystem tfs;

    tfs.typeName="Db Fs";
    tfs.structureLength = sizeof(Tcl_Filesystem);
    tfs.version = TCL_FILESYSTEM_VERSION_1;
    tfs.pathInFilesystemProc = inFsProc;

    /*...*/

    Tcl_FSRegister((void*),tfs);
}

int inFsProc(Tcl_Obj* pathPtr,ClientData* cd)
{
    /* How do I get my FSBackend struct here */
    FSBackend* bk = /* ? */

    int len;

    const char* searchPath = Tcl_GetStringFromObj(pathPtr,&len);

    char* foundPath = findFileInDb(searchPath,bk);

    if (foundPath == 0) {
        return -1;
    }

    cd = buildInternalRep(foundPath,bk);
    return TCL_OK;
}

/**
 ...
*/

int main()
{
    createFS("db1.db");
    createFS("db2.db");
}

如何在 inFsProc 中取回传递给 Tcl_FSRegister 的结构?

Tcl_FSData 函数说它可以得到它,但我需要得到一个 Tcl_Filesystem 指针

这很奇怪。 clientData 句柄 不是 用于指定挂载点,而是文件系统 type 的单独功能。 Tcl 内部使用 Tcl_FSRegister 根本不使用它。最接近规范使用的代码是 tclvfs 包。

https://github.com/tcl-mirror/tclvfs/blob/master/generic/vfs.c#L385 向我们展示了用法:

static void 
Vfs_RegisterWithInterp(interp)
    Tcl_Interp *interp;
{
    ClientData vfsAlreadyRegistered;
    /* 
     * We need to know if the interpreter is deleted, so we can
     * remove all interp-specific mounts.
     */
    Tcl_SetAssocData(interp, "vfs::inUse", (Tcl_InterpDeleteProc*) 
             Vfs_UnregisterWithInterp, (ClientData) 1);
    /* 
     * Perform one-off registering of our filesystem if that
     * has not happened before.
     */
    vfsAlreadyRegistered = Tcl_FSData(&vfsFilesystem);
    if (vfsAlreadyRegistered == NULL) {
        Tcl_FSRegister((ClientData)1, &vfsFilesystem);
        Tcl_CreateExitHandler(VfsExitProc, (ClientData)NULL);
        Tcl_CreateThreadExitHandler(VfsThreadExitProc, NULL);
    }
}

如您所见,clientData实际上只是用作标记,因此代码知道是否进行一次性初始化。

要发现装载映射是什么,您需要保留内部结构。强烈建议您在代码中使 Tcl_Filesystem 结构实例本身成为全局的(或者更确切地说 static 在文件范围内)。