using System.Threading;
using System.Net;
using System.Net.Sockets;
-using Mono.CSharp;
+using System.Collections.Generic;
-using Mono.Attach;
+using Mono.CSharp;
namespace Mono {
- public static class CSharpShell {
- static bool isatty = true;
+ public class Driver {
- static Mono.Terminal.LineEditor editor;
- static bool dumb;
+ static int Main (string [] args)
+ {
+#if !ON_DOTNET
+ if (args.Length > 0 && args [0] == "--attach") {
+ new ClientCSharpShell (Int32.Parse (args [1])).Run (null);
+ return 0;
+ }
- static void ConsoleInterrupt (object sender, ConsoleCancelEventArgs a)
+ if (args.Length > 0 && args [0].StartsWith ("--agent:")) {
+ new CSharpAgent (args [0]);
+ return 0;
+ }
+#endif
+ return Startup(args);
+ }
+
+ static int Startup (string[] args)
+ {
+ string[] startup_files;
+ try {
+ startup_files = Evaluator.InitAndGetStartupFiles (args);
+ Evaluator.DescribeTypeExpressions = true;
+ Evaluator.SetInteractiveBaseClass (typeof (InteractiveBaseShell));
+ } catch {
+ return 1;
+ }
+
+ return new CSharpShell ().Run (startup_files);
+ }
+ }
+
+ public class InteractiveBaseShell : InteractiveBase {
+ static bool tab_at_start_completes;
+
+ static InteractiveBaseShell ()
+ {
+ tab_at_start_completes = false;
+ }
+
+ internal static Mono.Terminal.LineEditor Editor;
+
+ public static bool TabAtStartCompletes {
+ get {
+ return tab_at_start_completes;
+ }
+
+ set {
+ tab_at_start_completes = value;
+ if (Editor != null)
+ Editor.TabAtStartCompletes = value;
+ }
+ }
+
+ public static new string help {
+ get {
+ return InteractiveBase.help +
+ " TabAtStartCompletes - Whether tab will complete even on emtpy lines\n";
+ }
+ }
+ }
+
+ public class CSharpShell {
+ static bool isatty = true, is_unix = false;
+ string [] startup_files;
+
+ Mono.Terminal.LineEditor editor;
+ bool dumb;
+
+ protected virtual void ConsoleInterrupt (object sender, ConsoleCancelEventArgs a)
{
// Do not about our program
a.Cancel = true;
Mono.CSharp.Evaluator.Interrupt ();
}
- static void SetupConsole ()
+ void SetupConsole ()
{
- string term = Environment.GetEnvironmentVariable ("TERM");
- dumb = term == "dumb" || term == null || isatty == false;
+ if (is_unix){
+ string term = Environment.GetEnvironmentVariable ("TERM");
+ dumb = term == "dumb" || term == null || isatty == false;
+ } else
+ dumb = false;
editor = new Mono.Terminal.LineEditor ("csharp", 300);
+ InteractiveBaseShell.Editor = editor;
+
+ editor.AutoCompleteEvent += delegate (string s, int pos){
+ string prefix = null;
+
+ string complete = s.Substring (0, pos);
+
+ string [] completions = Evaluator.GetCompletions (complete, out prefix);
+
+ return new Mono.Terminal.LineEditor.Completion (prefix, completions);
+ };
+
+#if false
+ //
+ // This is a sample of how completions sould be implemented.
+ //
+ editor.AutoCompleteEvent += delegate (string s, int pos){
+
+ // Single match: "Substring": Sub-string
+ if (s.EndsWith ("Sub")){
+ return new string [] { "string" };
+ }
+
+ // Multiple matches: "ToString" and "ToLower"
+ if (s.EndsWith ("T")){
+ return new string [] { "ToString", "ToLower" };
+ }
+ return null;
+ };
+#endif
+
Console.CancelKeyPress += ConsoleInterrupt;
}
- static string GetLine (bool primary)
+ string GetLine (bool primary)
{
string prompt = primary ? InteractiveBase.Prompt : InteractiveBase.ContinuationPrompt;
delegate string ReadLiner (bool primary);
- static void InitializeUsing ()
+ void InitializeUsing ()
{
Evaluate ("using System; using System.Linq; using System.Collections.Generic; using System.Collections;");
}
- static void InitTerminal ()
+ void InitTerminal ()
{
- isatty = UnixUtils.isatty (0) && UnixUtils.isatty (1);
+#if ON_DOTNET
+ is_unix = false;
+ isatty = true;
+#else
+ int p = (int) Environment.OSVersion.Platform;
+ is_unix = (p == 4) || (p == 128);
+
+ if (is_unix)
+ isatty = UnixUtils.isatty (0) && UnixUtils.isatty (1);
+ else
+ isatty = true;
+#endif
// Work around, since Console is not accounting for
// cursor position when writing to Stderr. It also
// has the undesirable side effect of making
// errors plain, with no coloring.
- Report.Stderr = Console.Out;
+// Report.Stderr = Console.Out;
SetupConsole ();
if (isatty)
}
- static void LoadStartupFiles ()
+ void ExecuteSources (IEnumerable<string> sources, bool ignore_errors)
+ {
+ foreach (string file in sources){
+ try {
+ try {
+ using (System.IO.StreamReader r = System.IO.File.OpenText (file)){
+ ReadEvalPrintLoopWith (p => r.ReadLine ());
+ }
+ } catch (FileNotFoundException){
+ Console.Error.WriteLine ("cs2001: Source file `{0}' not found", file);
+ return;
+ }
+ } catch {
+ if (!ignore_errors)
+ throw;
+ }
+ }
+ }
+
+ protected virtual void LoadStartupFiles ()
{
string dir = Path.Combine (
Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
if (!Directory.Exists (dir))
return;
- foreach (string file in Directory.GetFiles (dir)){
+ List<string> sources = new List<string> ();
+ List<string> libraries = new List<string> ();
+
+ foreach (string file in System.IO.Directory.GetFiles (dir)){
string l = file.ToLower ();
- if (l.EndsWith (".cs")){
- try {
- using (StreamReader r = File.OpenText (file)){
- ReadEvalPrintLoopWith (p => r.ReadLine ());
- }
- } catch {
- }
- } else if (l.EndsWith (".dll")){
- Evaluator.LoadAssembly (file);
- }
+ if (l.EndsWith (".cs"))
+ sources.Add (file);
+ else if (l.EndsWith (".dll"))
+ libraries.Add (file);
}
+
+ foreach (string file in libraries)
+ Evaluator.LoadAssembly (file);
+
+ ExecuteSources (sources, true);
}
- static void ReadEvalPrintLoopWith (ReadLiner readline)
+ void ReadEvalPrintLoopWith (ReadLiner readline)
{
string expr = null;
- while (true){
+ while (!InteractiveBase.QuitRequested){
string input = readline (expr == null);
if (input == null)
return;
}
}
- static public int ReadEvalPrintLoop ()
+ public int ReadEvalPrintLoop ()
{
- InitTerminal ();
+ if (startup_files != null && startup_files.Length == 0)
+ InitTerminal ();
InitializeUsing ();
LoadStartupFiles ();
- ReadEvalPrintLoopWith (GetLine);
+
+ //
+ // Interactive or startup files provided?
+ //
+ if (startup_files.Length != 0)
+ ExecuteSources (startup_files, false);
+ else
+ ReadEvalPrintLoopWith (GetLine);
return 0;
}
- static string Evaluate (string input)
+ protected virtual string Evaluate (string input)
{
bool result_set;
object result;
input = Evaluator.Evaluate (input, out result, out result_set);
if (result_set){
- PrettyPrint (result);
+ PrettyPrint (Console.Out, result);
Console.WriteLine ();
}
} catch (Exception e){
Console.WriteLine (e);
+ return null;
}
return input;
}
- static void p (string s)
+ static void p (TextWriter output, string s)
{
- Console.Write (s);
+ output.Write (s);
}
static string EscapeString (string s)
return s.Replace ("\"", "\\\"");
}
- static void PrettyPrint (object result)
+ static void EscapeChar (TextWriter output, char c)
+ {
+ if (c == '\''){
+ output.Write ("'\\''");
+ return;
+ }
+ if (c > 32){
+ output.Write ("'{0}'", c);
+ return;
+ }
+ switch (c){
+ case '\a':
+ output.Write ("'\\a'");
+ break;
+
+ case '\b':
+ output.Write ("'\\b'");
+ break;
+
+ case '\n':
+ output.Write ("'\\n'");
+ break;
+
+ case '\v':
+ output.Write ("'\\v'");
+ break;
+
+ case '\r':
+ output.Write ("'\\r'");
+ break;
+
+ case '\f':
+ output.Write ("'\\f'");
+ break;
+
+ case '\t':
+ output.Write ("'\\t");
+ break;
+
+ default:
+ output.Write ("'\\x{0:x}", (int) c);
+ break;
+ }
+ }
+
+ internal static void PrettyPrint (TextWriter output, object result)
{
if (result == null){
- p ("null");
+ p (output, "null");
return;
}
if (result is Array){
Array a = (Array) result;
- p ("{ ");
+ p (output, "{ ");
int top = a.GetUpperBound (0);
for (int i = a.GetLowerBound (0); i <= top; i++){
- PrettyPrint (a.GetValue (i));
+ PrettyPrint (output, a.GetValue (i));
if (i != top)
- p (", ");
+ p (output, ", ");
}
- p (" }");
+ p (output, " }");
} else if (result is bool){
if ((bool) result)
- p ("true");
+ p (output, "true");
else
- p ("false");
+ p (output, "false");
} else if (result is string){
- p (String.Format ("\"{0}\"", EscapeString ((string)result)));
+ p (output, String.Format ("\"{0}\"", EscapeString ((string)result)));
} else if (result is IDictionary){
IDictionary dict = (IDictionary) result;
int top = dict.Count, count = 0;
- p ("{");
+ p (output, "{");
foreach (DictionaryEntry entry in dict){
count++;
- p ("{ ");
- PrettyPrint (entry.Key);
- p (", ");
- PrettyPrint (entry.Value);
+ p (output, "{ ");
+ PrettyPrint (output, entry.Key);
+ p (output, ", ");
+ PrettyPrint (output, entry.Value);
if (count != top)
- p (" }, ");
+ p (output, " }, ");
else
- p (" }");
+ p (output, " }");
}
- p ("}");
+ p (output, "}");
} else if (result is IEnumerable) {
int i = 0;
- p ("{ ");
+ p (output, "{ ");
foreach (object item in (IEnumerable) result) {
if (i++ != 0)
- p (", ");
+ p (output, ", ");
- PrettyPrint (item);
+ PrettyPrint (output, item);
}
- p (" }");
+ p (output, " }");
+ } else if (result is char) {
+ EscapeChar (output, (char) result);
} else {
- p (result.ToString ());
+ p (output, result.ToString ());
}
}
- static int Main (string [] args)
+ public CSharpShell ()
{
- if (args.Length > 0 && args [0] == "--attach") {
- new AttachedCSharpShell (Int32.Parse (args [1]));
- return 0;
- } else if (args.Length > 0 && args [0].StartsWith ("--agent")) {
- new CSharpAgent (args [0]);
- return 0;
- }
+ }
- try {
- Evaluator.Init (args);
- } catch {
- return 1;
- }
-
+ public virtual int Run (string [] startup_files)
+ {
+ this.startup_files = startup_files;
return ReadEvalPrintLoop ();
}
+
}
-}
-/*
- * A shell connected to a CSharpAgent running in a remote process.
- * FIXME:
- * - using NOT.EXISTS works, but leads to an error later when mcs tries to search
- * that namespace.
- * - it would be nice to provide some kind of autocompletion even in remote mode.
- * - maybe add 'class_name' and 'method_name' arguments to LoadAgent.
- */
-class AttachedCSharpShell {
-
- public AttachedCSharpShell (int pid) {
- /* Create a server socket we listen on whose address is passed to the agent */
- TcpListener listener = new TcpListener (new IPEndPoint (IPAddress.Loopback, 0));
- listener.Start ();
-
- string agent_assembly = typeof (AttachedCSharpShell).Assembly.Location;
- string agent_arg = "--agent:" + ((IPEndPoint)listener.Server.LocalEndPoint).Port;
-
- VirtualMachine vm = new VirtualMachine (pid);
- vm.Attach (agent_assembly, agent_arg);
-
- /* Wait for the client to connect */
- TcpClient client = listener.AcceptTcpClient ();
- NetworkStream s = client.GetStream ();
- StreamReader sr = new StreamReader (s);
- StreamWriter sw = new StreamWriter (s);
-
- Console.WriteLine ("Connected.");
-
- InitTerminal ();
-
- sw.WriteLine ("using System; using System.Linq; using System.Collections.Generic; using System.Collections;");
- sw.Flush ();
- /* Read result */
- while (true) {
- string line = sr.ReadLine ();
- if (line == "<END>")
- break;
+#if !ON_DOTNET
+ //
+ // A shell connected to a CSharpAgent running in a remote process.
+ // - maybe add 'class_name' and 'method_name' arguments to LoadAgent.
+ // - Support Gtk and Winforms main loops if detected, this should
+ // probably be done as a separate agent in a separate place.
+ //
+ class ClientCSharpShell : CSharpShell {
+ NetworkStream ns, interrupt_stream;
+
+ public ClientCSharpShell (int pid)
+ {
+ // Create a server socket we listen on whose address is passed to the agent
+ TcpListener listener = new TcpListener (new IPEndPoint (IPAddress.Loopback, 0));
+ listener.Start ();
+ TcpListener interrupt_listener = new TcpListener (new IPEndPoint (IPAddress.Loopback, 0));
+ interrupt_listener.Start ();
+
+ string agent_assembly = typeof (ClientCSharpShell).Assembly.Location;
+ string agent_arg = String.Format ("--agent:{0}:{1}" ,
+ ((IPEndPoint)listener.Server.LocalEndPoint).Port,
+ ((IPEndPoint)interrupt_listener.Server.LocalEndPoint).Port);
+
+ var vm = new Attach.VirtualMachine (pid);
+ vm.Attach (agent_assembly, agent_arg);
+
+ /* Wait for the client to connect */
+ TcpClient client = listener.AcceptTcpClient ();
+ ns = client.GetStream ();
+ TcpClient interrupt_client = interrupt_listener.AcceptTcpClient ();
+ interrupt_stream = interrupt_client.GetStream ();
+
+ Console.WriteLine ("Connected.");
}
-
- //LoadStartupFiles ();
-
- string expr = "";
- bool eof = false;
- while (!eof) {
- string input = GetLine (expr == "");
- if (input == null)
- break;
-
- if (input == "")
- continue;
-
- sw.WriteLine (input);
- sw.Flush ();
-
- /* Read the (possible) error messages */
- while (true) {
- string line = sr.ReadLine ();
- if (line == null) {
- eof = true;
- break;
- }
- if (line == "<RESULT>")
- break;
- else
- // FIXME: Colorize
- Console.WriteLine (line);
- }
- /* Read the result */
- while (true) {
- string line = sr.ReadLine ();
- if (line == null) {
- eof = true;
- break;
- }
- if (line == "<INPUT>")
- break;
- else
- Console.WriteLine (line);
- }
- /* Read the (possible) incomplete input */
- expr = "";
+
+ //
+ // A remote version of Evaluate
+ //
+ protected override string Evaluate (string input)
+ {
+ ns.WriteString (input);
while (true) {
- string line = sr.ReadLine ();
- if (line == null) {
- eof = true;
+ AgentStatus s = (AgentStatus) ns.ReadByte ();
+
+ switch (s){
+ case AgentStatus.PARTIAL_INPUT:
+ return input;
+
+ case AgentStatus.ERROR:
+ string err = ns.GetString ();
+ Console.Error.WriteLine (err);
break;
+
+ case AgentStatus.RESULT_NOT_SET:
+ return null;
+
+ case AgentStatus.RESULT_SET:
+ string res = ns.GetString ();
+ Console.WriteLine (res);
+ return null;
}
- if (line == "<END>")
- break;
- else
- expr += line;
}
}
+
+ public override int Run (string [] startup_files)
+ {
+ // The difference is that we do not call Evaluator.Init, that is done on the target
+ return ReadEvalPrintLoop ();
+ }
+
+ protected override void ConsoleInterrupt (object sender, ConsoleCancelEventArgs a)
+ {
+ // Do not about our program
+ a.Cancel = true;
+
+ interrupt_stream.WriteByte (0);
+ int c = interrupt_stream.ReadByte ();
+ if (c != -1)
+ Console.WriteLine ("Execution interrupted");
+ }
+
}
- static bool isatty = true;
+ //
+ // Stream helper extension methods
+ //
+ public static class StreamHelper {
+ static DataConverter converter = DataConverter.LittleEndian;
- static Mono.Terminal.LineEditor editor;
- static bool dumb;
-
- static void ConsoleInterrupt (object sender, ConsoleCancelEventArgs a)
- {
- // Do not about our program
- a.Cancel = true;
-
- Mono.CSharp.Evaluator.Interrupt ();
- }
+ public static int GetInt (this Stream stream)
+ {
+ byte [] b = new byte [4];
+ if (stream.Read (b, 0, 4) != 4)
+ throw new IOException ("End reached");
+ return converter.GetInt32 (b, 0);
+ }
- static void SetupConsole ()
- {
- string term = Environment.GetEnvironmentVariable ("TERM");
- dumb = term == "dumb" || term == null || isatty == false;
-
- editor = new Mono.Terminal.LineEditor ("csharp", 300);
- Console.CancelKeyPress += ConsoleInterrupt;
- }
-
- static string GetLine (bool primary)
- {
- string prompt = primary ? InteractiveBase.Prompt : InteractiveBase.ContinuationPrompt;
-
- if (dumb){
- if (isatty)
- Console.Write (prompt);
-
- return Console.ReadLine ();
- } else {
- return editor.Edit (prompt, "");
+ public static string GetString (this Stream stream)
+ {
+ int len = stream.GetInt ();
+ byte [] b = new byte [len];
+ if (stream.Read (b, 0, len) != len)
+ throw new IOException ("End reached");
+ return Encoding.UTF8.GetString (b);
}
- }
-
- static void InitTerminal ()
- {
- isatty = UnixUtils.isatty (0) && UnixUtils.isatty (1);
-
- SetupConsole ();
-
- if (isatty)
- Console.WriteLine ("Mono C# Shell, type \"help;\" for help\n\nEnter statements below.");
- }
-}
-
-namespace Mono.Management
-{
- interface IVirtualMachine {
- void LoadAgent (string filename, string args);
- }
-}
-
-/*
- * This is the agent loaded into the target process when using --attach.
- */
-class CSharpAgent
-{
- public CSharpAgent (String arg) {
- new Thread (new ParameterizedThreadStart (Run)).Start (arg);
- }
-
- public void Run (object o) {
- string arg = (string)o;
- int port = Int32.Parse (arg.Substring (arg.IndexOf (":") + 1));
-
- Console.WriteLine ("csharp-agent: started, connecting to localhost:" + port);
-
- TcpClient client = new TcpClient ("127.0.0.1", port);
- Console.WriteLine ("csharp-agent: connected.");
-
- NetworkStream s = client.GetStream ();
-
- try {
- Evaluator.Init (new string [0]);
- } catch {
- return;
+
+ public static void WriteInt (this Stream stream, int n)
+ {
+ byte [] bytes = converter.GetBytes (n);
+ stream.Write (bytes, 0, bytes.Length);
}
-
- try {
- // Add all assemblies loaded later
- AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoaded;
-
- // Add all currently loaded assemblies
- foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies ())
- Evaluator.ReferenceAssembly (a);
-
- RunRepl (s);
- } finally {
- AppDomain.CurrentDomain.AssemblyLoad -= AssemblyLoaded;
- client.Close ();
- Console.WriteLine ("csharp-agent: disconnected.");
+
+ public static void WriteString (this Stream stream, string s)
+ {
+ stream.WriteInt (s.Length);
+ byte [] bytes = Encoding.UTF8.GetBytes (s);
+ stream.Write (bytes, 0, bytes.Length);
}
}
-
- static void AssemblyLoaded (object sender, AssemblyLoadEventArgs e) {
- Evaluator.ReferenceAssembly (e.LoadedAssembly);
+
+ public enum AgentStatus : byte {
+ // Received partial input, complete
+ PARTIAL_INPUT = 1,
+
+ // The result was set, expect the string with the result
+ RESULT_SET = 2,
+
+ // No result was set, complete
+ RESULT_NOT_SET = 3,
+
+ // Errors and warnings string follows
+ ERROR = 4,
}
+
+ //
+ // This is the agent loaded into the target process when using --attach.
+ //
+ class CSharpAgent
+ {
+ NetworkStream interrupt_stream;
+
+ public CSharpAgent (String arg)
+ {
+ new Thread (new ParameterizedThreadStart (Run)).Start (arg);
+ }
- public void RunRepl (NetworkStream s) {
- StreamReader r = new StreamReader (s);
- StreamWriter w = new StreamWriter (s);
- string input = null;
-
- Report.Stderr = w;
+ public void InterruptListener ()
+ {
+ while (true){
+ int b = interrupt_stream.ReadByte();
+ if (b == -1)
+ return;
+ Evaluator.Interrupt ();
+ interrupt_stream.WriteByte (0);
+ }
+ }
+
+ public void Run (object o)
+ {
+ string arg = (string)o;
+ string ports = arg.Substring (8);
+ int sp = ports.IndexOf (':');
+ int port = Int32.Parse (ports.Substring (0, sp));
+ int interrupt_port = Int32.Parse (ports.Substring (sp+1));
+
+ Console.WriteLine ("csharp-agent: started, connecting to localhost:" + port);
+
+ TcpClient client = new TcpClient ("127.0.0.1", port);
+ TcpClient interrupt_client = new TcpClient ("127.0.0.1", interrupt_port);
+ Console.WriteLine ("csharp-agent: connected.");
+
+ NetworkStream s = client.GetStream ();
+ interrupt_stream = interrupt_client.GetStream ();
+ new Thread (InterruptListener).Start ();
- while (true) {
try {
- string line = r.ReadLine ();
-
- bool result_set;
- object result;
-
- if (input == null)
- input = line;
- else
- input = input + "\n" + line;
-
- // This will print any error messages to w
- input = Evaluator.Evaluate (input, out result, out result_set);
-
- // FIXME: Emit XML
-
- // This separates the result from the possible error messages
- w.WriteLine ("<RESULT>");
- if (result_set) {
- if (result == null)
- w.Write ("null");
+ Evaluator.Init (new string [0]);
+ } catch {
+ // TODO: send a result back.
+ Console.WriteLine ("csharp-agent: initialization failed");
+ return;
+ }
+
+ try {
+ // Add all assemblies loaded later
+ AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoaded;
+
+ // Add all currently loaded assemblies
+ foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies ())
+ Evaluator.ReferenceAssembly (a);
+
+ RunRepl (s);
+ } finally {
+ AppDomain.CurrentDomain.AssemblyLoad -= AssemblyLoaded;
+ client.Close ();
+ interrupt_client.Close ();
+ Console.WriteLine ("csharp-agent: disconnected.");
+ }
+ }
+
+ static void AssemblyLoaded (object sender, AssemblyLoadEventArgs e)
+ {
+ Evaluator.ReferenceAssembly (e.LoadedAssembly);
+ }
+
+ public void RunRepl (NetworkStream s)
+ {
+ string input = null;
+
+ while (!InteractiveBase.QuitRequested) {
+ try {
+ string error_string;
+ StringWriter error_output = new StringWriter ();
+// Report.Stderr = error_output;
+
+ string line = s.GetString ();
+
+ bool result_set;
+ object result;
+
+ if (input == null)
+ input = line;
else
- w.Write (result.ToString ());
- w.WriteLine ();
+ input = input + "\n" + line;
+
+ try {
+ input = Evaluator.Evaluate (input, out result, out result_set);
+ } catch (Exception e) {
+ s.WriteByte ((byte) AgentStatus.ERROR);
+ s.WriteString (e.ToString ());
+ s.WriteByte ((byte) AgentStatus.RESULT_NOT_SET);
+ continue;
+ }
+
+ if (input != null){
+ s.WriteByte ((byte) AgentStatus.PARTIAL_INPUT);
+ continue;
+ }
+
+ // Send warnings and errors back
+ error_string = error_output.ToString ();
+ if (error_string.Length != 0){
+ s.WriteByte ((byte) AgentStatus.ERROR);
+ s.WriteString (error_output.ToString ());
+ }
+
+ if (result_set){
+ s.WriteByte ((byte) AgentStatus.RESULT_SET);
+ StringWriter sr = new StringWriter ();
+ CSharpShell.PrettyPrint (sr, result);
+ s.WriteString (sr.ToString ());
+ } else {
+ s.WriteByte ((byte) AgentStatus.RESULT_NOT_SET);
+ }
+ } catch (IOException) {
+ break;
+ } catch (Exception e){
+ Console.WriteLine (e);
}
- // FIXME: This might occur in the output as well.
- w.WriteLine ("<INPUT>");
- /* The rest of the input */
- w.WriteLine (input);
- w.WriteLine ("<END>");
- w.Flush ();
- } catch (IOException) {
- break;
- } catch (Exception e){
- Console.WriteLine (e);
}
}
}
-}
\ No newline at end of file
+
+ public class UnixUtils {
+ [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
+ extern static int _isatty (int fd);
+
+ public static bool isatty (int fd)
+ {
+ try {
+ return _isatty (fd) == 1;
+ } catch {
+ return false;
+ }
+ }
+ }
+#endif
+}
+
+namespace Mono.Management
+{
+ interface IVirtualMachine {
+ void LoadAgent (string filename, string args);
+ }
+}
+