2012-03-29 69 views
5

我有一個嵌入Tcl以執行一些Tcl代碼的小型shell應用程序。 Tcl解釋器使用Tcl_CreateInterp進行初始化。一切都非常簡單:由嵌入式Tcl運行時執行的句柄退出命令

  1. 用戶類型Tcl命令
  2. 命令被傳遞給Tcl_Eval評估
  3. 重複

但是,如果用戶鍵入「退出」,這是一個有效的Tcl命令,整個事情 - Tcl解釋器和我的shell應用程序 - 自動退出。

問:有沒有什麼辦法可以捕捉到來自Tcl解釋器的退出信號。我真的不想檢查每個用戶的命令。我試過Tcl_CreateExitHandler,但沒有奏效。

非常感謝。

+1

修正了標題並刪除了對「tcllib」的引用,因爲* Tcl [標準庫]通常被該名稱所知(http://tcllib.sourceforge.net/)。你似乎真正指的是將Tcl運行時嵌入到你的程序中。 – kostix 2012-03-29 08:08:09

+0

'Tcl_CreateExitHandler'用於捕獲退出並釋放資源(例如數據庫連接),否則這些資源會很快地出現。它無法阻止退出的發生。 – 2012-03-29 14:41:13

+0

這實際上正是我想要做的 - 在退出時釋放資源。爲什麼在這種情況下'Tcl_CreateExitHandler'不起作用? – ilya1725 2012-03-29 18:05:22

回答

0

使用Tcl_CreateExitHandler工作正常。問題在於我在處理程序實現中添加了printf,並且輸出未顯示在終端上。所以我認爲它沒有被調用。但是,在執行該處理程序時,不再有stdout。在應用程序上運行strace顯示處理程序正在正常執行。

此問題的另一種解決方案可以是使用atexit並在那裏處理退出事件。

8

擺脫命令

rename exit "" 

,或者重新定義它讓用戶知道這是禁用:

proc exit {args} { error "The exit command is not available in this context" } 

也是值得考慮的運行用戶在safe interp代碼,而不是在主貝殼。這樣做可以讓您精確控制用戶訪問的內容。

您可能也可以創建一個子interp(非安全),只是禁用該interp的退出命令。

最後,你可以只重命名退出到別的東西,如果你只是想避免用戶錯誤地鍵入它:

namespace eval ::hidden {} 
rename exit ::hidden::exit 
+0

這可以工作。但我仍然想保留'退出'電話。 – ilya1725 2012-03-29 01:50:41

+4

如果你想讓出口給你,但不給用戶,我會推薦安全的interp路由。 – RHSeeger 2012-03-29 02:35:24

+2

+1安全interp幾乎肯定是要走的路 – 2012-03-29 13:21:53

1

重命名exit命令:

rename exit __exit 

proc exit {args} { 
    puts -nonewline "Do you really want to exit? (y/n) " 
    flush stdout 
    gets stdin answer 
    if {$answer == "y"} { 
     __exit [lindex $args 0] 
    } 
} 

這樣,當用戶輸入exit時,他/她將執行您的自定義退出命令,您可以在其中執行任何您喜歡的操作。

+0

謝謝,海。但是,這仍然不能解決我的問題 - 如果從Tcl調用exit,我的整個C應用程序將無條件關閉。我仍然需要在退出時清理一些資源。 – ilya1725 2012-03-29 18:53:17