internal ConsoleThread(Interp i) { Name = "ConsoleThread"; interp = i; sbuf = new System.Text.StringBuilder(100); out_Renamed = TclIO.GetStdChannel(StdChannel.STDOUT); err = TclIO.GetStdChannel(StdChannel.STDERR); }
public override void ProcessIdleEvent() { // During the execution of this method, elements may be removed from the errors list (because a TCL.CompletionCode.BREAK was returned by the bgerror // command, or because the interp was deleted). We remove this BgError instance from the list first so that this instance won't // be deleted twice. SupportClass.VectorRemoveElement(EnclosingInstance.Errors, this); // Restore important state variables to what they were at the time the error occurred. try { EnclosingInstance.Interp.SetVar("errorInfo", null, ErrorInfo, TCL.VarFlag.GLOBAL_ONLY); } // Ignore any TclException's, possibly caused by variable traces on the errorInfo variable. This is compatible with the behavior of the Tcl C API. catch (TclException) { } try { EnclosingInstance.Interp.SetVar("errorCode", null, ErrorCode, TCL.VarFlag.GLOBAL_ONLY); } // Ignore any TclException's, possibly caused by variable traces on the errorCode variable. This is compatible with the behavior of the Tcl C API. catch (TclException) { } // Make sure, that the interpreter will surive the invocation of the bgerror command. EnclosingInstance.Interp.preserve(); try { // Invoke the bgerror command. TclObject[] argv = new TclObject[2]; argv[0] = EnclosingInstance.BgerrorCmdObj; argv[1] = ErrorMsg; Parser.EvalObjv(EnclosingInstance.Interp, argv, 0, TCL.EVAL_GLOBAL); } catch (TclException e) { switch (e.GetCompletionCode()) { case TCL.CompletionCode.ERROR: try { Channel chan = TclIO.GetStdChannel(StdChannel.STDERR); var interp = EnclosingInstance.Interp; if (EnclosingInstance.Interp.GetResult().ToString().Equals("\"bgerror\" is an invalid command name or ambiguous abbreviation")) { chan.Write(interp, ErrorInfo); chan.Write(interp, "\n"); } else { chan.Write(interp, "bgerror failed to handle background error.\n"); chan.Write(interp, " Original error: "); chan.Write(interp, ErrorMsg); chan.Write(interp, "\n"); chan.Write(interp, " Error in bgerror: "); chan.Write(interp, EnclosingInstance.Interp.GetResult()); chan.Write(interp, "\n"); } chan.Flush(EnclosingInstance.Interp); } catch (TclException) { } // Ignore. catch (IOException) { } // Ignore, too. break; case TCL.CompletionCode.BREAK: for (int i = EnclosingInstance.Errors.Count - 1; i >= 0; i--) { BgError bgError = (BgError)EnclosingInstance.Errors[i]; EnclosingInstance.Errors.RemoveAt(i); bgError.Cancel(); bgError.ErrorMsg.Release(); bgError.ErrorMsg = null; bgError.ErrorInfo.Release(); bgError.ErrorInfo = null; bgError.ErrorCode.Release(); bgError.ErrorCode = null; } break; } } EnclosingInstance.Interp.release(); ErrorMsg.Release(); ErrorMsg = null; ErrorInfo.Release(); ErrorInfo = null; ErrorCode.Release(); ErrorCode = null; }
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); } }