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_test.cc b/aos/util/scoped_pipe_test.cc
index 183688e..c71e272 100644
--- a/aos/util/scoped_pipe_test.cc
+++ b/aos/util/scoped_pipe_test.cc
@@ -1,5 +1,7 @@
#include "aos/util/scoped_pipe.h"
+#include <fcntl.h>
+
#include <array>
#include <string>
@@ -11,39 +13,45 @@
// Tests using uint32_t read/write methods on the ScopedPipe objects.
TEST(ScopedPipeTest, IntegerPipe) {
- std::tuple<ScopedPipe::ScopedReadPipe, ScopedPipe::ScopedWritePipe>
- pipe = ScopedPipe::MakePipe();
- ASSERT_FALSE(std::get<0>(pipe).Read().has_value())
+ ScopedPipe::PipePair pipe = ScopedPipe::MakePipe();
+ ASSERT_FALSE(pipe.read->Read().has_value())
<< "Shouldn't get anything on empty read.";
- std::get<1>(pipe).Write(971);
- ASSERT_EQ(971, std::get<0>(pipe).Read().value());
+ pipe.write->Write(971);
+ ASSERT_EQ(971, pipe.read->Read().value());
}
// Tests using string read/write methods on the ScopedPipe objects.
TEST(ScopedPipeTest, StringPipe) {
- std::tuple<ScopedPipe::ScopedReadPipe, ScopedPipe::ScopedWritePipe>
- pipe = ScopedPipe::MakePipe();
+ ScopedPipe::PipePair pipe = ScopedPipe::MakePipe();
std::string buffer;
- ASSERT_EQ(0u, std::get<0>(pipe).Read(&buffer))
+ ASSERT_EQ(0u, pipe.read->Read(&buffer))
<< "Shouldn't get anything on empty read.";
ASSERT_TRUE(buffer.empty());
const char *const kAbc = "abcdef";
- std::get<1>(pipe).Write(
+ pipe.write->Write(
absl::Span<const uint8_t>(reinterpret_cast<const uint8_t *>(kAbc), 6));
- ASSERT_EQ(6u, std::get<0>(pipe).Read(&buffer));
+ ASSERT_EQ(6u, pipe.read->Read(&buffer));
ASSERT_EQ("abcdef", buffer);
std::array<uint8_t, 10000> large_buffer;
large_buffer.fill(99);
- std::get<1>(pipe).Write(
+ pipe.write->Write(
absl::Span<const uint8_t>(large_buffer.data(), large_buffer.size()));
- ASSERT_EQ(large_buffer.size(), std::get<0>(pipe).Read(&buffer));
+ ASSERT_EQ(large_buffer.size(), pipe.read->Read(&buffer));
for (size_t ii = 0; ii < large_buffer.size(); ++ii) {
ASSERT_EQ(large_buffer[ii], buffer[ii + 6]);
}
}
+// Tests that calling SetCloexec succeeds and does indeed set FD_CLOEXEC.
+TEST(ScopedPipeTest, SetCloexec) {
+ ScopedPipe::PipePair pipe = ScopedPipe::MakePipe();
+ ASSERT_EQ(0, fcntl(pipe.read->fd(), F_GETFD) & FD_CLOEXEC);
+ pipe.read->SetCloexec();
+ ASSERT_NE(0, fcntl(pipe.read->fd(), F_GETFD) & FD_CLOEXEC);
+}
+
} // namespace testing
} // namespace util
} // namespace aos