2012-03-29 10 views
5

Mam małą aplikację powłoki, która osadza Tcl, aby wykonać jakiś zestaw kodu Tcl. Interpreter Tcl jest inicjowany za pomocą Tcl_CreateInterp. Wszystko jest bardzo proste: komenda rodzajeObsługa polecenia wyjścia wykonywanego przez wbudowane środowisko wykonawcze Tcl

  1. użytkowników Tcl
  2. polecenie zostanie przekazany do Tcl_Eval oceny
  3. powtórz

Ale jeśli użytkownik wpisze „exit”, który jest ważny Tcl polecenie, cała sprawa - interpreter Tcl i moja aplikacja powłoki - wyjście automatycznie.

P: czy istnieje sposób, aby złapać ten sygnał wyjściowy pochodzący z interpretera Tcl. Naprawdę nie chciałbym sprawdzać każdego polecenia użytkownika. Próbowałem Tcl_CreateExitHandler, ale to nie zadziałało.

Dziękuję bardzo.

+1

Naprawiono tytuł i usunięto odniesienia do "tcllib", ponieważ znormalizowana biblioteka * dla * Tcl [jest powszechnie znana pod tą nazwą] (http://tcllib.sourceforge.net/). Wydaje się, że to, na co naprawdę masz na myśli, to osadzanie środowiska wykonawczego Tcl w twoim programie. – kostix

+0

'Tcl_CreateExitHandler' służy do wychwytywania wyjść i zwalniania zasobów (np. Połączeń z bazami danych), które w innym przypadku byłyby nieprzyjemne. Nie może powstrzymać wyjścia. –

+0

To jest dokładnie to, co chcę zrobić - zwolnij zasoby przy wyjściu. Dlaczego w tym przypadku nie działa "Tcl_CreateExitHandler"? – ilya1725

Odpowiedz

0

Używanie Tcl_CreateExitHandler działa dobrze. Problem polegał na tym, że dodałem printf do implementacji programu obsługi, a dane wyjściowe nie pojawiły się na terminalu. Więc pomyślałem, że to nie zostało wywołane. Jednakże, do czasu wykonania tego programu obsługi nie ma już żadnej wartości. Uruchomienie strace aplikacji wskazuje, że program obsługi jest wykonywany poprawnie.

Innym rozwiązaniem tego problemu może być użycie atexit i przetworzenie zdarzenia wyjściowego.

8

Pozbądź polecenia

rename exit "" 

Albo przedefiniować go, aby użytkownik mógł wiedzieć, że jest wyłączone:

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

również warte rozważenia jest uruchomiony kod użytkownika w safe interp zamiast w głównym muszla. Pozwoli ci to kontrolować dokładnie to, do czego użytkownik ma dostęp.

Możliwe może być również utworzenie interp dziecka (nie-bezpiecznego) i po prostu wyłączenie polecenia wyjścia dla tego interp.

Wreszcie, można po prostu zmienić nazwę wyjścia do czegoś innego, jeśli tylko stara się uniknąć użytkownicy wpisując go przez pomyłkę:

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

To może zadziałać. Ale nadal chciałbym zachować wywołanie "wyjścia". – ilya1725

+4

Jeśli chcesz mieć wyjście dostępne dla ciebie, ale nie dla użytkownika, poleciłbym bezpieczną drogę interp. – RHSeeger

+2

Bezpieczny interp +1 to prawie na pewno sposób na przejście na –

1

Zmiana nazwy komendy 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] 
    } 
} 

ten sposób , kiedy typ użytkownika to exit, on/ona wykona twoje niestandardowe polecenie wyjścia, w którym możesz zrobić cokolwiek chcesz.

+0

Dzięki, Hai. Jednak to nadal nie rozwiązuje mojego problemu - jeśli 'exit' jest wywoływane z Tcl, to cała moja aplikacja C zamyka się bezwarunkowo. Nadal potrzebuję oczyścić niektóre zasoby przy wyjściu. – ilya1725

Powiązane problemy