1

我正在尝试使用 Tclapi 为 Tcl 编写一个自定义文件系统(它与工作相关,不会详细介绍),但我一直试图弄清楚为什么这不起作用。

在这个代码段中,我得到了原始/本地 Tcl_Filesystem,将其所有内容(函数指针)复制到 my_fs,然后在 my_fs 上调用 Tcl_FSRegister。很简单,认为它应该工作。

// global scope
const Tcl_Filesystem *ori_fs;
Tcl_Filesystem *my_fs;

...

// in Init

// Get the original Tcl_Filesystem.
Tcl_Obj *root_obj = Tcl_NewStringObj("/", -1);
Tcl_IncrRefCount(root_obj);
ori_fs = Tcl_FSGetFileSystemForPath(root_obj);
Tcl_DecrRefCount(root_obj);

// create a duplicate of the original Tcl_Filesystem struct.
my_fs = malloc(sizeof(Tcl_Filesystem));
memmove(my_fs, ori_fs, ori_fs->structureLength);

int ret = Tcl_FSRegister((ClientData)1, my_fs);
if (ret == TCL_ERROR) {
...

当我跑

load <path to .so>/my_fs[info sharedlibextension]

# sanity check
puts [pwd]

set fp [open test.txt]

但是,我明白了

<my current directory>

while executing
"open test.txt"
    invoked from within
"set fp [open test.txt]"
    (file "test.tcl" line 3)

注意“puts [pwd]”是如何工作的,但不是“open test.txt”?

在对 Tcl_FSRegister 的调用中用“ori_fs”替换“my_fs”似乎可行……我已经花了太多时间试图弄清楚这一点。如果有人可以帮助我,我将不胜感激!

4

1 回答 1

1

本机文件系统很特殊。特别是在某些地方直接使用了它的身份:例如,它是唯一可以在其上制作临时文件的 FS,假定它拥有根,并且在路径管理中对其进行了特殊处理。(好吧,根据源代码中对 Tcl 内部变量的直接引用tclNativeFilesystem,这不是你可以欺骗的东西。它也可能在只读存储器中,所以你不能绕过这个。)

对于 Tcl 虚拟文件系统的大多数正常使用来说,这无关紧要。临时文件必须是本地的,因为您很可能会将它们传递给操作系统(例如,用于加载库或运行 VFS 内的程序;使用这些,它们必须被复制出来,否则操作系统会认为“<em>what你在说什么?!”)然后你把你正在安装的东西放在本地根以外的地方。只要您不尝试使用 VFS 作为安全措施(推荐;有安全的解释器,因为它们提供了更强大的沙盒解决方案),这应该不是问题,因为您可以让您的代码知道它需要在特定位置下方工作才能完成任务。(FWIW,这是一个坏主意cd无论如何,除了响应用户请求,因为它改变了用户提供的相对路径的含义,所以好的代码从一开始就处理“使一切都相对于定义的位置”。)

于 2016-09-24T18:32:38.083 回答