tcl

saving and restoring all local and env variables in Tcl


In an overly complex tcl file, I want to save all local and env variables in a file before sourcing anotehr tcl script and once the script finishes I want to restore all the local and env variables. Something like this:

save_all_local_vars save_all_env_vars

do_something

unset_all_local_vars unset_all_env_vars

restore_all_local_vars restore_all_env_vars

so at the end of the script I am sure that the whole environment is exactly matching to what I have before running 'do_something'


Solution

  • By far the simplest way of doing this is to use a separate interpreter for the other script. The only things that interpreters share by default are environment variables and the current working directory (they are true process globals) and if you mark the interpreter as a safe interpreter, those are not exposed.

    Note that the boundary between interpreters is considered to be a security domain boundary. Child interpreters cannot affect their parents in any way that the parent does not explicitly permit.


    In the simplest case, you do this:

    interp create other
    set result [other eval [list source $theFile]]
    interp delete other
    

    Saving environment variables with array get and array set is left as an exercise. Similarly for the working directory with pwd and cd.

    Any operation you want the other code to do that will persist to your main interpreter should be mapped in via an alias (interp alias). You have control over what the target of the alias does; all the other code can do is call it with some arguments.


    If you mark the interpreter as safe (interp create -safe) then everything that could possibly be used to do real mischief is hidden. Including source. You probably need to read the file on behalf of the interpreter.

    Aliases are more important with safe interpreters. They represent the safe/trusted equivalent of a system call.