public void disposeAssocData(Interp interp) // Current interpreter. { // There shouldn't be any commands left. if (!(interp.slaveTable.Count == 0)) { System.Console.Error.WriteLine("InterpInfoDeleteProc: still exist commands"); } interp.slaveTable = null; // Tell any interps that have aliases to this interp that they should // delete those aliases. If the other interp was already dead, it // would have removed the target record already. // TODO ATK foreach (WrappedCommand slaveCmd in new ArrayList(interp.targetTable.Keys)) { Interp slaveInterp = (Interp)interp.targetTable[slaveCmd]; slaveInterp.deleteCommandFromToken(slaveCmd); } interp.targetTable = null; if (interp.interpChanTable != null) { foreach (Channel channel in new ArrayList(interp.interpChanTable.Values)) { TclIO.unregisterChannel(interp, channel); } } if (interp.slave.interpCmd != null) { // Tcl_DeleteInterp() was called on this interpreter, rather // "interp delete" or the equivalent deletion of the command in the // master. First ensure that the cleanup callback doesn't try to // delete the interp again. interp.slave.slaveInterp = null; interp.slave.masterInterp.deleteCommandFromToken(interp.slave.interpCmd); } // There shouldn't be any aliases left. if (!(interp.aliasTable.Count == 0)) { System.Console.Error.WriteLine("InterpInfoDeleteProc: still exist aliases"); } interp.aliasTable = null; }
/// <summary> This procedure is invoked to process the "close" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { Channel chan; /* The channel being operated on this method */ if (argv.Length != 2) { throw new TclNumArgsException(interp, 1, argv, "channelId"); } chan = TclIO.getChannel(interp, argv[1].ToString()); if (chan == null) { throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\""); } TclIO.unregisterChannel(interp, chan); return(TCL.CompletionCode.RETURN); }
public static void Tcl_UnregisterChannel(Interp interp, Channel chan) { TclIO.unregisterChannel(interp, chan); }
public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv) { if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "cmd ?arg ...?"); } int cmd = TclIndex.get(interp, objv[1], options, "option", 0); switch (cmd) { case OPT_ALIAS: { if (objv.Length >= 4) { Interp slaveInterp = getInterp(interp, objv[2]); if (objv.Length == 4) { InterpAliasCmd.describe(interp, slaveInterp, objv[3]); return(TCL.CompletionCode.RETURN); } if ((objv.Length == 5) && ("".Equals(objv[4].ToString()))) { InterpAliasCmd.delete(interp, slaveInterp, objv[3]); return(TCL.CompletionCode.RETURN); } if (objv.Length > 5) { Interp masterInterp = getInterp(interp, objv[4]); if ("".Equals(objv[5].ToString())) { if (objv.Length == 6) { InterpAliasCmd.delete(interp, slaveInterp, objv[3]); return(TCL.CompletionCode.RETURN); } } else { InterpAliasCmd.create(interp, slaveInterp, masterInterp, objv[3], objv[5], 6, objv); return(TCL.CompletionCode.RETURN); } } } throw new TclNumArgsException(interp, 2, objv, "slavePath slaveCmd ?masterPath masterCmd? ?args ..?"); } case OPT_ALIASES: { Interp slaveInterp = getInterp(interp, objv); InterpAliasCmd.list(interp, slaveInterp); break; } case OPT_CREATE: { // Weird historical rules: "-safe" is accepted at the end, too. bool safe = interp.isSafe; TclObject slaveNameObj = null; bool last = false; for (int i = 2; i < objv.Length; i++) { if ((!last) && (objv[i].ToString()[0] == '-')) { int index = TclIndex.get(interp, objv[i], createOptions, "option", 0); if (index == OPT_CREATE_SAFE) { safe = true; continue; } i++; last = true; } if (slaveNameObj != null) { throw new TclNumArgsException(interp, 2, objv, "?-safe? ?--? ?path?"); } slaveNameObj = objv[i]; } if (slaveNameObj == null) { // Create an anonymous interpreter -- we choose its name and // the name of the command. We check that the command name // that we use for the interpreter does not collide with an // existing command in the master interpreter. int i = 0; while (interp.getCommand("interp" + i) != null) { i++; } slaveNameObj = TclString.newInstance("interp" + i); } InterpSlaveCmd.create(interp, slaveNameObj, safe); interp.setResult(slaveNameObj); break; } case OPT_DELETE: { for (int i = 2; i < objv.Length; i++) { Interp slaveInterp = getInterp(interp, objv[i]); if (slaveInterp == interp) { throw new TclException(interp, "cannot delete the current interpreter"); } InterpSlaveCmd slave = slaveInterp.slave; slave.masterInterp.deleteCommandFromToken(slave.interpCmd); } break; } case OPT_EVAL: { if (objv.Length < 4) { throw new TclNumArgsException(interp, 2, objv, "path arg ?arg ...?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.eval(interp, slaveInterp, 3, objv); break; } case OPT_EXISTS: { bool exists = true; try { getInterp(interp, objv); } catch (TclException e) { if (objv.Length > 3) { throw; } exists = false; } interp.setResult(exists); break; } case OPT_EXPOSE: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "path hiddenCmdName ?cmdName?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.expose(interp, slaveInterp, 3, objv); break; } case OPT_HIDE: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "path cmdName ?hiddenCmdName?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.hide(interp, slaveInterp, 3, objv); break; } case OPT_HIDDEN: { Interp slaveInterp = getInterp(interp, objv); InterpSlaveCmd.hidden(interp, slaveInterp); break; } case OPT_ISSAFE: { Interp slaveInterp = getInterp(interp, objv); interp.setResult(slaveInterp.isSafe); break; } case OPT_INVOKEHIDDEN: { bool global = false; int i; for (i = 3; i < objv.Length; i++) { if (objv[i].ToString()[0] != '-') { break; } int index = TclIndex.get(interp, objv[i], hiddenOptions, "option", 0); if (index == OPT_HIDDEN_GLOBAL) { global = true; } else { i++; break; } } if (objv.Length - i < 1) { throw new TclNumArgsException(interp, 2, objv, "path ?-global? ?--? cmd ?arg ..?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.invokeHidden(interp, slaveInterp, global, i, objv); break; } case OPT_MARKTRUSTED: { if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "path"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.markTrusted(interp, slaveInterp); break; } case OPT_SLAVES: { Interp slaveInterp = getInterp(interp, objv); TclObject result = TclList.newInstance(); interp.setResult(result); IEnumerator keys = slaveInterp.slaveTable.Keys.GetEnumerator(); while (keys.MoveNext()) { string inString = (string)keys.Current; TclList.append(interp, result, TclString.newInstance(inString)); } break; } case OPT_SHARE: { if (objv.Length != 5) { throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath"); } Interp masterInterp = getInterp(interp, objv[2]); Channel chan = TclIO.getChannel(masterInterp, objv[3].ToString()); if (chan == null) { throw new TclException(interp, "can not find channel named \"" + objv[3].ToString() + "\""); } Interp slaveInterp = getInterp(interp, objv[4]); TclIO.registerChannel(slaveInterp, chan); break; } case OPT_TARGET: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "path alias"); } Interp slaveInterp = getInterp(interp, objv[2]); string aliasName = objv[3].ToString(); Interp targetInterp = InterpAliasCmd.getTargetInterp(slaveInterp, aliasName); if (targetInterp == null) { throw new TclException(interp, "alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" not found"); } if (!getInterpPath(interp, targetInterp)) { throw new TclException(interp, "target interpreter for alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" is not my descendant"); } break; } case OPT_TRANSFER: { if (objv.Length != 5) { throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath"); } Interp masterInterp = getInterp(interp, objv[2]); Channel chan = TclIO.getChannel(masterInterp, objv[3].ToString()); if (chan == null) { throw new TclException(interp, "can not find channel named \"" + objv[3].ToString() + "\""); } Interp slaveInterp = getInterp(interp, objv[4]); TclIO.registerChannel(slaveInterp, chan); TclIO.unregisterChannel(masterInterp, chan); break; } } return(TCL.CompletionCode.RETURN); }
private static void makeSafe(Interp interp) { Channel chan; // Channel to remove from safe interpreter. interp.hideUnsafeCommands(); interp.isSafe = true; // Unsetting variables : (which should not have been set // in the first place, but...) // No env array in a safe slave. try { interp.unsetVar("env", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } // Remove unsafe parts of tcl_platform try { interp.unsetVar("tcl_platform", "os", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } try { interp.unsetVar("tcl_platform", "osVersion", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } try { interp.unsetVar("tcl_platform", "machine", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } try { interp.unsetVar("tcl_platform", "user", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } // Unset path informations variables // (the only one remaining is [info nameofexecutable]) try { interp.unsetVar("tclDefaultLibrary", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } try { interp.unsetVar("tcl_library", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } try { interp.unsetVar("tcl_pkgPath", TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { } // Remove the standard channels from the interpreter; safe interpreters // do not ordinarily have access to stdin, stdout and stderr. // // NOTE: These channels are not added to the interpreter by the // Tcl_CreateInterp call, but may be added later, by another I/O // operation. We want to ensure that the interpreter does not have // these channels even if it is being made safe after being used for // some time.. chan = TclIO.getStdChannel(StdChannel.STDIN); if (chan != null) { TclIO.unregisterChannel(interp, chan); } chan = TclIO.getStdChannel(StdChannel.STDOUT); if (chan != null) { TclIO.unregisterChannel(interp, chan); } chan = TclIO.getStdChannel(StdChannel.STDERR); if (chan != null) { TclIO.unregisterChannel(interp, chan); } }