AU: Execute postinst asynchronously so that the D-Bus service is not blocked.

This CL also cleans up Subprocess memory handling a bit and extends it to
capture the output of asynchronous subprocesses. Also adds a scoped temp mount
unmounter utility class.

BUG=8937
TEST=unit tests, tested on the device -- making sure no D-Bus calls timeou
during postinstall.

Change-Id: I219dda3dc98d875ff05050f1a32ffcc925db1d53

Review URL: http://codereview.chromium.org/4690006
diff --git a/subprocess_unittest.cc b/subprocess_unittest.cc
index 679f85c..314e0ae 100644
--- a/subprocess_unittest.cc
+++ b/subprocess_unittest.cc
@@ -27,18 +27,35 @@
 namespace {
 const int kLocalHttpPort = 8088;
 
-void Callback(int return_code, void *p) {
+void Callback(int return_code, const string& output, void *p) {
   EXPECT_EQ(256, return_code);
   GMainLoop* loop = reinterpret_cast<GMainLoop*>(p);
   g_main_loop_quit(loop);
 }
 
+void CallbackEcho(int return_code, const string& output, void *p) {
+  EXPECT_EQ(0, return_code);
+  EXPECT_NE(string::npos, output.find("this is stdout"));
+  EXPECT_NE(string::npos, output.find("this is stderr"));
+  GMainLoop* loop = reinterpret_cast<GMainLoop*>(p);
+  g_main_loop_quit(loop);
+}
+
 gboolean LaunchFalseInMainLoop(gpointer data) {
   vector<string> cmd;
   cmd.push_back("/bin/false");
   Subprocess::Get().Exec(cmd, Callback, data);
   return FALSE;
 }
+
+gboolean LaunchEchoInMainLoop(gpointer data) {
+  vector<string> cmd;
+  cmd.push_back("/bin/sh");
+  cmd.push_back("-c");
+  cmd.push_back("echo this is stdout; echo this is stderr > /dev/stderr");
+  Subprocess::Get().Exec(cmd, CallbackEcho, data);
+  return FALSE;
+}
 }  // namespace {}
 
 TEST(SubprocessTest, SimpleTest) {
@@ -48,8 +65,15 @@
   g_main_loop_unref(loop);
 }
 
+TEST(SubprocessTest, EchoTest) {
+  GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
+  g_timeout_add(0, &LaunchEchoInMainLoop, loop);
+  g_main_loop_run(loop);
+  g_main_loop_unref(loop);
+}
+
 namespace {
-void CallbackBad(int return_code, void *p) {
+void CallbackBad(int return_code, const string& output, void *p) {
   CHECK(false) << "should never be called.";
 }