public void TestSpawn() { Spawn spawn; UnixReader reader; string[] argv = { "/bin/cat" }; UnixStream stream; StreamWriter writer; int stdin, stdout, stderr; spawn = new Spawn (); spawn.SpawnAsyncWithPipes (null, argv, null, GSpawnFlags.G_SPAWN_DO_NOT_REAP_CHILD, null, out pid, out stdin, out stdout, out stderr); pids_matched = false; exit_status_is_good = false; spawn.ChildWatchAdd (pid, child_watch_cb); stream = new UnixStream (stdin, true); writer = new StreamWriter (stream); writer.Write ("Hello, world!"); writer.Close (); /* this will close the stdin fd */ reader = new UnixReader (stdout); reader.DataAvailable += data_available_cb; reader.Closed += closed_cb; string_equal = false; closed = false; loop = new MainLoop (); loop.Run (); Assert.IsTrue (string_equal, "Read the correct string"); Assert.IsTrue (closed, "UnixReader got closed"); Assert.IsTrue (pids_matched, "PID of child process"); Assert.IsTrue (exit_status_is_good, "Exit status of child process"); }
public void Run(Aggregator aggregator, string[] argv, string stdin_str) { if (state != State.PreRun) throw new ApplicationException ("Tried to Run() an AggregatorRunner which was not in PreRun state"); if (aggregator == null) throw new ArgumentNullException ("aggregator"); if (argv == null) throw new ArgumentNullException ("argv"); this.aggregator = aggregator; try { int[] pipe; spawn = new Spawn (); pipe = new int[2]; if (unix.pipe (pipe) != 0) throw new UnixIOException (Mono.Unix.Native.Stdlib.GetLastError ()); Spawn.ChildSetupFunc child_setup_fn = delegate () { int process_group; UnixStream child_stream; StreamWriter child_writer; process_group = unix.setsid (); child_stream = new UnixStream (pipe[1], false); child_writer = new StreamWriter (child_stream); child_writer.Write ("{0}\n", process_group); child_writer.Close (); }; spawn.SpawnAsyncWithPipes (null, argv, null, GSpawnFlags.G_SPAWN_DO_NOT_REAP_CHILD | GSpawnFlags.G_SPAWN_SEARCH_PATH, child_setup_fn, out child_pid, out child_stdin, out child_stdout, out child_stderr); child_watch_id = spawn.ChildWatchAdd (child_pid, child_watch_cb); UnixStream parent_stream; StreamReader parent_reader; string str; parent_stream = new UnixStream (pipe[0], false); parent_reader = new StreamReader (parent_stream); str = parent_reader.ReadLine (); parent_reader.Close (); child_process_group = int.Parse (str); if (child_process_group == -1) throw new ApplicationException ("Could not get the child process group"); state = State.Running; stdout_reader = new UnixReader (child_stdout); stdout_reader.DataAvailable += stdout_reader_data_available_cb; stdout_reader.Closed += stdout_reader_closed_cb; stderr_reader = new UnixReader (child_stderr); stderr_reader.DataAvailable += stderr_reader_data_available_cb; stderr_reader.Closed += stderr_reader_closed_cb; line_reader = new LineReader (); line_reader.LineAvailable += line_reader_line_available_cb; if (stdin_str != null) write_stdin_to_child (stdin_str); } catch (GException e) { Console.WriteLine ("error when spawning: {0}", e); /* FIXME: report something better --- re-throw the exception here? */ state = State.Error; } }