Justin Ryan wrote:
> I run Tcl scripts inside of a larger long-running Java system (along
> the lines of JSR-223, but using tcl.lang classes directly), and I've
> found some behavior which I found a little odd in Jacl. The tcl exit
> command calls System.exit(), which makes sense when running a single
> script. But it proves to be prohibitive when I'm containing the
> Interpreter inside a larger system. I'm looking for an exit command to
> kindly exit the evalFile/eval method or throw an exception indicating
> that the Interp in now invalid. This might already be taken of when
> putting the Interpreter into safe mode, is this true and is there
> documentation concerning the state of the Safe Interpreter in
> tcljava/jacl?
>
> My workaround, in case anyone is interested is to overwrite the exit
> command. I prep the Interpreter before running any untrusted code:
>
> interp.eval("rename exit ::tcl::exit");
> interp.createCommand("exit", new SafeExitCommand() );
>
> My new exit command looks like this:
>
> public class SafeExitCommand implements Command {
> public void cmdProc(Interp interp, TclObject argv[])
> throws TclException {
> int code = 0;
>
> if (argv.length > 2)
> throw new TclNumArgsException(interp,
> 1, argv, "?returnCode?");
>
> if (argv.length == 2) {
> code = TclInteger.get(interp, argv[1]);
> }
>
> throw new TclException(interp, "ExitCommand "
> + Integer.toString(code) );
> }
> }
>
> I then look for a TclException with a message (e.getMessage()) with
> the word ExitCommand. It's definitely hacky, but it works for me. An
> alternative would be to set the ccode of TclException to something
> like TCL.EXIT, and then look for that code like TCL.RETURN is looked
> for. Is that a valid idea to persue and contribute?
>
> justin
>
>
Hi Justin
The approach you mention may work out for you. My only suggestion is to
take a
look at the new "interrupted" feature in Jacl 1.4. You can replace the
exit command
in the safe interp with a command that invokes Interp.setInterrupted().
When this
exception is raised, the call stack will be unwound and the interp will
be cleaned
up in the event processing thread. You could also invoke this method via
reflection
from a Tcl script if you like.
I hope that helps
Mo
|