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 への呼び出しで「my_fs」を「ori_fs」に置き換えるとうまくいくようです...これを理解するために、すでに多くの時間を費やしてきました。誰かがこれで私を助けてくれれば幸いです!

4

1 に答える 1

1

ネイティブ ファイルシステムは特別です。特に、その ID が直接使用される場所がいくつかあります。たとえば、一時ファイルを作成できる唯一の FS であり、ルートを所有していると見なされ、パス管理で特別に処理されます。(まあ、ソースコードのどこにTcl内部変数への直接参照があるかによるとtclNativeFilesystem、これはチートできるものではありません。おそらく読み取り専用メモリにあるので、これをハックすることはできません。)

Tcl 仮想ファイルシステムの通常の用途では、これは問題ではありません。一時ファイルはネイティブである必要があります。これは、一時ファイルを OS に渡す可能性があるためです (たとえば、ライブラリをロードしたり、VFS 内にあるプログラムを実行したりするため)。あなたは話しているのですか?!」) そして、マウントしているものをネイティブルート以外の場所に置きます。VFS をセキュリティ対策として使用しようとしない限り (お勧めしません。より強力なサンドボックス ソリューションを提供するため、安全なインタープリターがあります)、コードにそれを知らせるだけで問題ありません。物事を成し遂げるためには、特定の場所の下で動作する必要があります。(FWIW、それは悪い考えですcdとにかく、ユーザーの要求に応じる場合を除いて、ユーザーが指定した相対パスの意味が変わるため、適切なコードは最初から「すべてを定義された場所に相対的にする」ことを処理します。)

于 2016-09-24T18:32:38.083 に答える