2016-09-24 43 views
1

我想爲Tcl編寫一個自定義文件系統使用Tclapi(它的工作相關,不會進入細節),但我堅持嘗試弄清楚爲什麼這不起作用。tcl「打開」命令不工作時替換Tcl_Filesystem與重複

在這段代碼中,我得到原始/本機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) 

注意如何 「把[密碼]」 的作品,但不是 「開放的test.txt」?

在調用Tcl_FSRegister時用「ori_fs」替換「my_fs」似乎可行... 我已經花費了太多的時間來解決這個問題。如果有人能幫助我,我將不勝感激!

回答

1

本地文件系統是特殊的。特別是有些地方可以直接使用它的身份:例如,它是唯一可以擁有臨時文件的FS,它被認爲擁有根,並且在路徑管理中專門處理。 (好吧,根據源代碼中的哪個地方,直接引用了Tcl內部變量tclNativeFilesystem,這不是你可以欺騙的東西,也可能是隻讀存儲器,所以你不能繞過這個)。

對於大多數Tcl虛擬文件系統的正常使用,這並不重要。臨時文件必須是本機的,因爲您可能將它們傳遞給操作系統(例如,用於加載庫或運行VFS內部的程序;這些文件必須複製出來,否則操作系統會認爲「」談論?!「),並且你把東西安裝在原生根以外的地方。只要你不嘗試使用VFS作爲安全措施(建議使用而不是;由於它們提供了更強大的沙盒解決方案,因此有安全的解釋器),它不應該是一個問題,因爲你可以讓你的代碼知道它需要在特定位置下工作才能完成任務。 (FWIW,無論如何,cd是一個壞主意,除了響應用戶請求,因爲它改變了用戶提供的相對路徑的含義,所以好的代碼句柄「從一開始就使所有相對於定義的位置」)。