Add support for capturing stdout/err in Application

This also makes it so that the Application object can poll instead of
just relying on SIGCHLD to watch for application stops, to make it a bit
cleaner for simple use-cases.

Change-Id: I8af71e1dd89e0cfa1b189ba1e5264df0df9b9560
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/util/scoped_pipe.cc b/aos/util/scoped_pipe.cc
index 36bc1b3..d677b07 100644
--- a/aos/util/scoped_pipe.cc
+++ b/aos/util/scoped_pipe.cc
@@ -26,13 +26,21 @@
   return *this;
 }
 
-std::tuple<ScopedPipe::ScopedReadPipe, ScopedPipe::ScopedWritePipe>
-ScopedPipe::MakePipe() {
+ScopedPipe::PipePair ScopedPipe::MakePipe() {
   int fds[2];
   PCHECK(pipe(fds) != -1);
   PCHECK(fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK) != -1);
   PCHECK(fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL) | O_NONBLOCK) != -1);
-  return {ScopedReadPipe(fds[0]), ScopedWritePipe(fds[1])};
+  return {std::unique_ptr<ScopedReadPipe>(new ScopedReadPipe(fds[0])),
+          std::unique_ptr<ScopedWritePipe>(new ScopedWritePipe(fds[1]))};
+}
+
+void ScopedPipe::SetCloexec() {
+  // FD_CLOEXEC is the only known file descriptor flag, but call GETFD just in
+  // case.
+  int flags = fcntl(fd(), F_GETFD);
+  PCHECK(flags != -1);
+  PCHECK(fcntl(fd(), F_SETFD, flags | FD_CLOEXEC) != -1);
 }
 
 size_t ScopedPipe::ScopedReadPipe::Read(std::string *buffer) {