2012-03-29 13 views
5

Tengo una aplicación de shell pequeña que incrusta Tcl para ejecutar algún conjunto de código Tcl. El intérprete Tcl se inicializa utilizando Tcl_CreateInterp. Todo es muy simple: tiposComando de salida de control ejecutado por tiempo de ejecución de Tcl incrustado

  1. usuario de comandos de Tcl
  2. el comando se pasa a Tcl_Eval para la evaluación
  3. repetición

Pero si un usuario escribe 'salida', que es un Tcl válida comando, todo el asunto - intérprete Tcl y mi aplicación de shell - salir automáticamente.

P: ¿Hay alguna forma de que pueda captar esta señal de salida procedente del intérprete Tcl? Realmente me gustaría no verificar cada comando de usuario. Intenté Tcl_CreateExitHandler, pero no funcionó.

Muchas gracias.

+1

Se corrigió el título y se eliminaron las referencias a "tcllib" porque una biblioteca estandarizada * para * Tcl [se conoce comúnmente con ese nombre] (http://tcllib.sourceforge.net/). A lo que parece hacer referencia en realidad es a la incrustación del tiempo de ejecución de Tcl en su programa. – kostix

+0

'Tcl_CreateExitHandler' es para interceptar salidas y liberar recursos (p. Ej., Conexiones de bases de datos) que de lo contrario se mantienen. No puede evitar que ocurra una salida. –

+0

Eso es exactamente lo que quiero hacer: liberar recursos al salir. ¿Por qué no funcionaría 'Tcl_CreateExitHandler' en este caso? – ilya1725

Respuesta

0

El uso de Tcl_CreateExitHandler funciona bien. El problema fue que agregué un printf en la implementación del controlador y la salida no apareció en el terminal. Entonces pensé que no había sido llamado. Sin embargo, en el momento en que se ejecuta este controlador no hay más stdout. Al ejecutar strace en la aplicación, se muestra que el controlador se está ejecutando correctamente.

Otra solución a este problema puede ser utilizar atexit y procesar el evento de salida allí.

8

Deshacerse del comando

rename exit "" 

O redefinirlo para que el usuario sepa que es discapacitado:

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

También vale la pena considerar se está ejecutando el código del usuario en un safe interp en lugar de en el principal cáscara. Hacerlo le permitiría controlar exactamente a qué tiene acceso el usuario.

También es posible que pueda crear un interp del niño (no seguro) y simplemente deshabilite el comando de salida para esa interpelación.

Por último, usted podría simplemente cambiar el nombre de la salida a otra cosa, si sólo está tratando de evitar que los usuarios escribir por error:

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

Eso puede funcionar. Pero aún me gustaría conservar la llamada de 'salida'. – ilya1725

+4

Si desea que la salida esté disponible para usted, pero no para el usuario, le recomiendo la ruta interp segura. – RHSeeger

+2

+1 interp seguro es casi seguro que es el camino a seguir –

1

Cambie el nombre del comando 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] 
    } 
} 

esta manera , cuando el usuario escriba exit, ejecutará su comando de salida personalizado, en el que puede hacer lo que quiera.

+0

Gracias, Hai. Sin embargo, esto todavía no resuelve mi problema: si se llama a 'exit' desde Tcl, toda mi aplicación C se cierra incondicionalmente. Todavía necesito limpiar algunos recursos al salir. – ilya1725

Cuestiones relacionadas