Обработка команды выхода, выполняемой встроенной средой выполнения Tcl - PullRequest
5 голосов
/ 29 марта 2012

У меня есть небольшое приложение оболочки, которое встраивает Tcl для выполнения некоторого набора кода Tcl. Интерпретатор Tcl инициализируется с использованием Tcl_CreateInterp. Все очень просто:

  1. пользователь вводит команду Tcl
  2. команда передается в Tcl_Eval для оценки
  3. повтор

Но если пользователь вводит команду 'exit', которая является допустимой командой Tcl, все - интерпретатор Tcl и мое приложение оболочки - завершается автоматически.

В: есть ли какой-нибудь способ, которым я могу уловить этот сигнал выхода, поступающий от интерпретатора Tcl. Я действительно хотел бы не проверять каждую пользовательскую команду. Я пытался Tcl_CreateExitHandler , но это не сработало.

Большое спасибо.

Ответы [ 3 ]

8 голосов
/ 29 марта 2012

Избавьтесь от команды

rename exit ""

Или переопределите ее, чтобы сообщить пользователю, что она отключена:

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

Стоит также рассмотреть запуск кода пользователя в безопасное взаимодействие вместо основной оболочки.Это позволит вам точно контролировать, к чему у пользователя есть доступ.

Вы также можете создать дочерний интерфейс (небезопасный) и просто отключить команду выхода для этого интерфейса.

Наконец, вы можете просто переименовать выход на что-то другое, если вы только пытаетесь избежать того, чтобы пользователи вводили его по ошибке:

namespace eval ::hidden {}
rename exit ::hidden::exit
1 голос
/ 29 марта 2012

Переименуйте команду 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 голосов
/ 29 марта 2012

Использование Tcl_CreateExitHandler работает нормально.Проблема заключалась в том, что я добавил printf в реализацию обработчика, и вывод не появился на терминале.Поэтому я подумал, что это не называется.Однако ко времени выполнения этого обработчика stdout больше нет.Запуск strace в приложении показывает, что обработчик выполняется нормально.

Другим решением этой проблемы может быть использование atexit и обработка там события выхода.

...