[fbl][unique_fd] Add duplicate call.
This is a fairly common lifecycle management operation.
Tested: runtests -t fbl-test
Change-Id: I0ea7cfb81f1df1d338b4aa66f97f4fd71c260adc
diff --git a/system/ulib/fbl/include/fbl/unique_fd.h b/system/ulib/fbl/include/fbl/unique_fd.h
index b439941..d9e5b77 100644
--- a/system/ulib/fbl/include/fbl/unique_fd.h
+++ b/system/ulib/fbl/include/fbl/unique_fd.h
@@ -42,6 +42,10 @@
// move semantics only
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(unique_fd);
+ fbl::unique_fd duplicate() {
+ return fbl::unique_fd(dup(fd_));
+ }
+
int release() {
int t = fd_;
fd_ = InvalidValue();
diff --git a/system/utest/fbl/unique_fd_tests.cpp b/system/utest/fbl/unique_fd_tests.cpp
index 42c6c0e..27d81a9 100644
--- a/system/utest/fbl/unique_fd_tests.cpp
+++ b/system/utest/fbl/unique_fd_tests.cpp
@@ -191,6 +191,28 @@
END_TEST;
}
+bool duplicate_test() {
+ BEGIN_TEST;
+ int pipes[2];
+ EXPECT_EQ(pipe(pipes), 0);
+
+ fbl::unique_fd in(pipes[1]);
+ fbl::unique_fd out(pipes[0]);
+ EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
+ {
+ fbl::unique_fd in2 = in.duplicate();
+ fbl::unique_fd out2 = out.duplicate();
+ EXPECT_TRUE(verify_pipes_open(in2.get(), out2.get()));
+
+ EXPECT_TRUE(verify_pipes_open(in2.get(), out.get()));
+ EXPECT_TRUE(verify_pipes_open(in.get(), out2.get()));
+ EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
+ }
+ EXPECT_TRUE(verify_pipes_open(in.get(), out.get()));
+
+ END_TEST;
+}
+
} // namespace
BEGIN_TEST_CASE(unique_fd_tests)
@@ -200,4 +222,5 @@
RUN_TEST(swap_test)
RUN_TEST(move_test)
RUN_TEST(reset_test)
+RUN_TEST(duplicate_test)
END_TEST_CASE(unique_fd_tests)