/////////////////////////////////////////////////////////////////////// public override string GetString( Interpreter interpreter, string name, CultureInfo cultureInfo, ref Result error ) { if (!enableGetString) { return(base.GetString( interpreter, name, cultureInfo, ref error)); } if (name != null) { return(String.Format( "interpreter: {0}, name: {1}, cultureInfo: {2}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(name), FormatOps.WrapOrNull(cultureInfo))); } else { error = "invalid string name"; return(null); } }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 1) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-force", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-fail", null), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-message", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-current", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 1) { code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if ((argumentIndex == Index.Invalid) || ((argumentIndex + 1) == arguments.Count)) { bool force = false; if (options.IsPresent("-force")) { force = true; } bool fail = false; if (options.IsPresent("-fail")) { fail = true; } Variant value = null; string message = null; if (options.IsPresent("-message", ref value)) { message = value.ToString(); } // // NOTE: The default exit code is "success" (i.e. zero). // ExitCode exitCode = ResultOps.SuccessExitCode(); if (options.IsPresent("-current")) { exitCode = interpreter.ExitCode; } // // NOTE: Was an exit code specified in the command? // if (argumentIndex != Index.Invalid) { object enumValue = EnumOps.TryParseEnum( typeof(ExitCode), arguments[argumentIndex], true, true, ref result); if (enumValue is ExitCode) { exitCode = (ExitCode)enumValue; } else { result = ScriptOps.BadValue( null, "exit code", arguments[argumentIndex], Enum.GetNames(typeof(ExitCode)), null, ", or an integer"); code = ReturnCode.Error; } } // // NOTE: Make sure we succeeded at coverting the exit code to an integer. // if (code == ReturnCode.Ok) { // // NOTE: Make sure the interpreter host, if any, agrees to exit (i.e. it may deny the // request if the application is doing something that should not be interrupted). // code = interpreter.CanExit(exitCode, force, fail, message, ref result); if (code == ReturnCode.Ok) { // // NOTE: Exit the application (either by marking the current interpreter as "exited" // or physically exiting the containing process). // TraceOps.DebugTrace(String.Format( "Execute: {0}, interpreter = {1}, message = {2}", force && fail ? "forcibly failing" : force ? "forcibly exiting" : "exiting", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(message)), typeof(Exit).Name, TracePriority.Command); if (force) { #if !MONO if (fail && !CommonOps.Runtime.IsMono()) { try { // // NOTE: Using this method to exit a script is NOT recommended unless // you are trying to prevent damaging another part of the system. // // MONO: This method is not supported by the Mono runtime. // Environment.FailFast(message); /* NOT REACHED */ result = "failed to exit process"; code = ReturnCode.Error; } catch (Exception e) { result = e; code = ReturnCode.Error; } } else #endif { // // BUGFIX: Try to dispose our containing interpreter now. We must do // this to prevent it from being disposed on a random GC thread. // try { interpreter.Dispose(); interpreter = null; } catch (Exception e) { result = e; code = ReturnCode.Error; } // // NOTE: If we could not dispose the interpreter properly, complain; // however, keep exiting anyway. // if (code != ReturnCode.Ok) { DebugOps.Complain(interpreter, code, result); } try { // // NOTE: Using this method to exit a script is NOT recommended unless // you are running a standalone script in the Eagle Shell (i.e. // you are not hosted within another application). // Environment.Exit((int)exitCode); /* NOT REACHED */ result = "failed to exit process"; code = ReturnCode.Error; } catch (Exception e) { result = e; code = ReturnCode.Error; } } } else { interpreter.ExitCode = exitCode; interpreter.Exit = true; result = String.Empty; code = ReturnCode.Ok; } } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"exit ?options? ?returnCode?\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"exit ?options? ?returnCode?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-debug", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-commandline", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-dequote", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-quoteall", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-unicode", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-ignorestderr", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-killonerror", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-keepnewline", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noexitcode", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocapture", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-shell", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocarriagereturns", null), // simple switch new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-trimall", null), // simple switch new Option(typeof(ExitCode), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-success", null), // success exit code new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-domainname", null), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-username", null), new Option(null, OptionFlags.MustHaveSecureStringValue, Index.Invalid, Index.Invalid, "-password", null), new Option(null, OptionFlags.MustHaveListValue, Index.Invalid, Index.Invalid, "-preprocessarguments", null), // command new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-directory", null), // directory name new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-processid", null), // varName for processId new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-exitcode", null), // varName for exitCode new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-stdin", null), // varName for StdIn input new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-stdout", null), // varName for StdOut output new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-stderr", null), // varName for StdErr output new Option(typeof(EventFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-eventflags", new Variant(interpreter.EngineEventFlags)), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if (argumentIndex != Index.Invalid) { bool debug = false; if (options.IsPresent("-debug")) { debug = true; } bool commandLine = false; if (options.IsPresent("-commandline")) { commandLine = true; } bool dequote = false; if (options.IsPresent("-dequote")) { dequote = true; } bool quoteAll = false; if (options.IsPresent("-quoteall")) { quoteAll = true; } bool captureExitCode = true; if (options.IsPresent("-noexitcode")) { captureExitCode = false; } bool captureInput = true; bool captureOutput = true; if (options.IsPresent("-nocapture")) { captureInput = false; captureOutput = false; } bool useUnicode = false; if (options.IsPresent("-unicode")) { useUnicode = true; } bool ignoreStdErr = false; if (options.IsPresent("-ignorestderr")) { ignoreStdErr = true; } bool killOnError = false; if (options.IsPresent("-killonerror")) { killOnError = true; } bool keepNewLine = false; if (options.IsPresent("-keepnewline")) { keepNewLine = true; } bool carriageReturns = true; if (options.IsPresent("-nocarriagereturns")) { carriageReturns = false; } bool trimAll = false; if (options.IsPresent("-trimall")) { trimAll = true; } bool useShellExecute = false; if (options.IsPresent("-shell")) { useShellExecute = true; } Variant value = null; ExitCode?successExitCode = null; if (options.IsPresent("-success", ref value)) { successExitCode = (ExitCode)value.Value; } string domainName = null; if (options.IsPresent("-domainname", ref value)) { domainName = value.ToString(); } string userName = null; if (options.IsPresent("-username", ref value)) { userName = value.ToString(); } SecureString password = null; if (options.IsPresent("-password", ref value)) { password = (SecureString)value.Value; } string directory = null; if (options.IsPresent("-directory", ref value)) { directory = value.ToString(); } string processIdVarName = null; if (options.IsPresent("-processid", ref value)) { processIdVarName = value.ToString(); } string exitCodeVarName = null; if (options.IsPresent("-exitcode", ref value)) { exitCodeVarName = value.ToString(); } string stdInVarName = null; if (options.IsPresent("-stdin", ref value)) { stdInVarName = value.ToString(); } string stdOutVarName = null; if (options.IsPresent("-stdout", ref value)) { stdOutVarName = value.ToString(); } string stdErrVarName = null; if (options.IsPresent("-stderr", ref value)) { stdErrVarName = value.ToString(); } EventFlags eventFlags = interpreter.EngineEventFlags; if (options.IsPresent("-eventflags", ref value)) { eventFlags = (EventFlags)value.Value; } StringList list = null; if (options.IsPresent("-preprocessarguments", ref value)) { list = (StringList)value.Value; } int argumentStopIndex = arguments.Count - 1; bool background = false; if (arguments[arguments.Count - 1] == Characters.Ampersand.ToString()) { argumentStopIndex--; background = true; } string execFileName = arguments[argumentIndex]; if (!PathOps.IsRemoteUri(execFileName)) { execFileName = PathOps.GetNativePath(execFileName); } string execArguments = null; if ((argumentIndex + 1) < arguments.Count) { if (commandLine) { execArguments = RuntimeOps.BuildCommandLine( ArgumentList.GetRangeAsStringList(arguments, argumentIndex + 1, argumentStopIndex, dequote), quoteAll); } else { execArguments = ListOps.Concat(arguments, argumentIndex + 1, argumentStopIndex); } } Result input = null; if ((code == ReturnCode.Ok) && !useShellExecute && captureInput && (stdInVarName != null)) { code = interpreter.GetVariableValue(VariableFlags.None, stdInVarName, ref input, ref result); } if (debug) { TraceOps.DebugTrace(String.Format( "Execute: interpreter = {0}, domainName = {1}, userName = {2}, " + "password = {3}, execFileName = {4}, execArguments = {5}, " + "directory = {6}, input = {7}, eventFlags = {8}, debug = {9}, " + "commandLine = {10}, dequote = {11}, quoteAll = {12}, " + "useShellExecute = {13}, captureExitCode = {14}, " + "captureInput = {15}, captureOutput = {16}, useUnicode = {17}, " + "ignoreStdErr = {18}, killOnError = {19}, keepNewLine = {20}, " + "carriageReturns = {21}, trimAll = {22}, background = {23}, " + "successExitCode = {24}, processIdVarName = {25}, exitCodeVarName = {26}, " + "stdInVarName = {27}, stdOutVarName = {28}, stdErrVarName = {29}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(domainName), FormatOps.WrapOrNull(userName), FormatOps.WrapOrNull(password), FormatOps.WrapOrNull(execFileName), FormatOps.WrapOrNull(execArguments), FormatOps.WrapOrNull(directory), FormatOps.WrapOrNull(input), FormatOps.WrapOrNull(eventFlags), debug, commandLine, dequote, quoteAll, useShellExecute, captureExitCode, captureInput, captureOutput, useUnicode, ignoreStdErr, killOnError, keepNewLine, carriageReturns, trimAll, background, FormatOps.WrapOrNull(successExitCode), FormatOps.WrapOrNull(processIdVarName), FormatOps.WrapOrNull(exitCodeVarName), FormatOps.WrapOrNull(stdInVarName), FormatOps.WrapOrNull(stdOutVarName), FormatOps.WrapOrNull(stdErrVarName)), typeof(Exec).Name, TracePriority.Command); } int processId = 0; ExitCode exitCode = ResultOps.SuccessExitCode(); Result error = null; if (code == ReturnCode.Ok) { if (list != null) { list.Add(execFileName); list.Add(directory); list.Add(execArguments); code = interpreter.EvaluateScript(list.ToString(), ref result); if (code == ReturnCode.Return) { execArguments = result; code = ReturnCode.Ok; } else if (code == ReturnCode.Continue) { code = ReturnCode.Ok; goto done; } } if (code == ReturnCode.Ok) { code = ProcessOps.ExecuteProcess( interpreter, domainName, userName, password, execFileName, execArguments, directory, input, eventFlags, useShellExecute, captureExitCode, captureOutput, useUnicode, ignoreStdErr, killOnError, keepNewLine, background, !background, ref processId, ref exitCode, ref result, ref error); } } done: if (debug) { TraceOps.DebugTrace(String.Format( "Execute: interpreter = {0}, domainName = {1}, userName = {2}, " + "password = {3}, execFileName = {4}, execArguments = {5}, " + "directory = {6}, input = {7}, eventFlags = {8}, debug = {9}, " + "commandLine = {10}, dequote = {11}, quoteAll = {12}, " + "useShellExecute = {13}, captureExitCode = {14}, " + "captureInput = {15}, captureOutput = {16}, useUnicode = {17}, " + "ignoreStdErr = {18}, killOnError = {19}, keepNewLine = {20}, " + "carriageReturns = {21}, trimAll = {22}, background = {23}, " + "successExitCode = {24}, processIdVarName = {25}, exitCodeVarName = {26}, " + "stdInVarName = {27}, stdOutVarName = {28}, stdErrVarName = {29}, " + "processId = {30}, exitCode = {31}, result = {32}, error = {33}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(domainName), FormatOps.WrapOrNull(userName), FormatOps.WrapOrNull(password), FormatOps.WrapOrNull(execFileName), FormatOps.WrapOrNull(execArguments), FormatOps.WrapOrNull(directory), FormatOps.WrapOrNull(input), FormatOps.WrapOrNull(eventFlags), debug, commandLine, dequote, quoteAll, useShellExecute, captureExitCode, captureInput, captureOutput, useUnicode, ignoreStdErr, killOnError, keepNewLine, carriageReturns, trimAll, background, FormatOps.WrapOrNull(successExitCode), FormatOps.WrapOrNull(processIdVarName), FormatOps.WrapOrNull(exitCodeVarName), FormatOps.WrapOrNull(stdInVarName), FormatOps.WrapOrNull(stdOutVarName), FormatOps.WrapOrNull(stdErrVarName), processId, exitCode, FormatOps.WrapOrNull(true, true, result), FormatOps.WrapOrNull(true, true, error)), typeof(Exec).Name, TracePriority.Command); } // // NOTE: Even upon failure, always set the variable to contain // process Id, if applicable. // if (processIdVarName != null) { /* IGNORED */ interpreter.SetVariableValue( /* EXEMPT */ VariableFlags.NoReady, processIdVarName, processId.ToString(), null); } if (code == ReturnCode.Ok) { // // NOTE: Remove all carriage returns from output (leaving // only line feeds as line separators)? // if (!carriageReturns) { if (!String.IsNullOrEmpty(result)) { result = result.Replace( Characters.CarriageReturnString, String.Empty); } if (!String.IsNullOrEmpty(error)) { error = error.Replace( Characters.CarriageReturnString, String.Empty); } } // // NOTE: Remove all surrounding whitespace from the output? // if (trimAll) { if (!String.IsNullOrEmpty(result)) { result = result.Trim(); } if (!String.IsNullOrEmpty(error)) { error = error.Trim(); } } // // NOTE: Now, "result" contains any StdOut output and "error" // contains any StdErr output. // if ((code == ReturnCode.Ok) && !background && captureExitCode && (exitCodeVarName != null)) { code = interpreter.SetVariableValue(VariableFlags.None, exitCodeVarName, exitCode.ToString(), null, ref error); } if ((code == ReturnCode.Ok) && !useShellExecute && !background && captureOutput && (stdOutVarName != null)) { code = interpreter.SetVariableValue(VariableFlags.None, stdOutVarName, result, null, ref error); } if ((code == ReturnCode.Ok) && !useShellExecute && !background && captureOutput && (stdErrVarName != null)) { code = interpreter.SetVariableValue(VariableFlags.None, stdErrVarName, error, null, ref error); } // // NOTE: If they specified a "success" exit code, make sure // that is the same as the exit code we actually got // from the process. // if ((code == ReturnCode.Ok) && !background && captureExitCode && (successExitCode != null) && (exitCode != successExitCode)) { /* IGNORED */ interpreter.SetVariableValue( /* EXEMPT */ Engine.ErrorCodeVariableFlags, TclVars.ErrorCode, StringList.MakeList( "CHILDSTATUS", processId, exitCode), null); Engine.SetErrorCodeSet(interpreter, true); error = "child process exited abnormally"; code = ReturnCode.Error; } if (code != ReturnCode.Ok) { // // NOTE: Transfer error to command result. // result = error; } } else { // // NOTE: Transfer error to command result. // result = error; } } else { result = "wrong # args: should be \"exec ?options? arg ?arg ...?\""; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"exec ?options? arg ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }