2012-03-29 25 views
5

Tôi có một ứng dụng vỏ nhỏ nhúng Tcl để thực thi một số bộ mã Tcl. Trình thông dịch Tcl được khởi tạo bằng Tcl_CreateInterp. Mọi thứ đều rất đơn giản: các loạiXử lý lệnh thoát được thực thi bởi thời gian chạy Tcl nhúng

  1. dùng Tcl lệnh
  2. lệnh được thông qua để Tcl_Eval để đánh giá
  3. lặp lại

Nhưng nếu người sử dụng đánh 'exit', mà là một Tcl hợp lệ lệnh, toàn bộ điều - trình thông dịch Tcl và ứng dụng trình bao của tôi - tự động thoát.

Q: Có cách nào tôi có thể bắt tín hiệu thoát này đến từ thông dịch viên Tcl hay không. Tôi thực sự không muốn kiểm tra mọi lệnh của người dùng. Tôi đã thử Tcl_CreateExitHandler, nhưng nó không hoạt động.

Cảm ơn rất nhiều.

+1

Cố định tiêu đề và các tham chiếu đã xóa thành "tcllib" vì một thư viện chuẩn * cho * Tcl [thường được gọi bằng tên đó] (http://tcllib.sourceforge.net/). Những gì bạn dường như thực sự đề cập đến là nhúng thời gian chạy Tcl vào chương trình của bạn. – kostix

+0

'Tcl_CreateExitHandler' là để bẫy các lối thoát và phát hành tài nguyên (ví dụ: kết nối cơ sở dữ liệu) nếu không treo xung quanh một cách nhanh chóng. Nó không thể ngăn chặn một lối thoát xảy ra. –

+0

Đó thực sự chính xác là những gì tôi muốn làm - giải phóng tài nguyên khi thoát. Tại sao 'Tcl_CreateExitHandler' không hoạt động trong trường hợp này? – ilya1725

Trả lời

0

Sử dụng Tcl_CreateExitHandler hoạt động tốt. Vấn đề là tôi đã thêm một printf vào việc thực hiện trình xử lý và đầu ra không hiển thị trên thiết bị đầu cuối. Vì vậy, tôi nghĩ rằng nó đã không được gọi. Tuy nhiên, do thời gian xử lý này được thực hiện, không còn stdout nữa. Chạy strace trên ứng dụng cho thấy rằng trình xử lý đang được thực hiện tốt.

Một giải pháp khác cho vấn đề này có thể là sử dụng atexit và xử lý sự kiện thoát tại đó.

8

Loại bỏ các lệnh

rename exit "" 

Hoặc xác định lại nó để cho người dùng biết đó là khuyết tật:

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

Cũng đáng xem xét là chạy mã của người dùng trong một safe interp thay vì trong chính vỏ. Làm như vậy sẽ cho phép bạn kiểm soát chính xác những gì người dùng có quyền truy cập.

Bạn cũng có thể tạo ra một con interp (không an toàn) và chỉ cần vô hiệu hóa lệnh thoát cho interp đó.

Cuối cùng, bạn chỉ có thể đổi tên exit để cái gì khác, nếu bạn chỉ cố gắng để tránh người dùng gõ nó do nhầm lẫn:

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

Điều đó có thể hoạt động. Nhưng tôi vẫn muốn bảo vệ cuộc gọi 'thoát'. – ilya1725

+4

Nếu bạn muốn có lối thoát có sẵn cho bạn, nhưng không phải cho người dùng, tôi khuyên bạn nên sử dụng tuyến đường interp an toàn. – RHSeeger

+2

+1 interp an toàn gần như chắc chắn là cách để đi –

1

Đổi tên exit lệnh:

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] 
    } 
} 

Bằng cách này , khi người dùng nhập exit, họ sẽ thực hiện lệnh thoát tùy chỉnh của bạn, trong đó bạn có thể làm bất cứ điều gì bạn thích.

+0

Cảm ơn, Hải. Tuy nhiên, điều này vẫn không giải quyết vấn đề của tôi - nếu 'thoát' được gọi từ Tcl toàn bộ ứng dụng C của tôi đóng vô điều kiện. Tôi vẫn cần phải dọn sạch một số tài nguyên khi thoát. – ilya1725

Các vấn đề liên quan