Reputation: 4968
I have a small shell application that embeds Tcl to execute some set of Tcl code. The Tcl interpreter is initialized using Tcl_CreateInterp. Everything is very simple:
But if a user types 'exit', which is a valid Tcl command, the whole thing - Tcl interpreter and my shell application - exit automatically.
Q: is there any way I can catch this exit signal coming from Tcl interpreter. I really would like not to check every user command. I tried Tcl_CreateExitHandler, but it didn't work.
Thanks so much.
Upvotes: 6
Views: 1198
Reputation: 4968
Using Tcl_CreateExitHandler
works fine. The problem was that I added a printf
into the handler implementation and the output didn't show up on the terminal. So I thought it hasn't been called. However, by the time this handler is executed there is no stdout
any more. Running strace
on the application shows that the handler is being executed fine.
Another solution to this problem can be to use atexit and process the exit event there.
Upvotes: 0
Reputation: 40773
Rename the exit
command:
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]
}
}
This way, when the user type exit
, he/she will execute your custom exit command, in which you can do anything you like.
Upvotes: 2
Reputation: 16282
Get rid of the command
rename exit ""
Or redefine it to let the user know it's disabled:
proc exit {args} { error "The exit command is not available in this context" }
Also worth considering is running the user's code in a safe interp instead of in the main shell. Doing so would allow you to control exactly what the user has access to.
You might also be able to create a child interp (non-safe) and just disable the exit command for that interp.
Lastly, you could just rename exit to something else, if you're only trying to avoid users typing it by mistake:
namespace eval ::hidden {}
rename exit ::hidden::exit
Upvotes: 9