Add EFD_SEMAPHORE flag for eventfd.

Add a test for the new flag and add a test for the EFD_CLOEXEC flag.

Test: New unit tests pass on glibc and target.
Change-Id: Ib7a6ea4aadbd67ba8a523b6114a49fb8d6a43f12
diff --git a/tests/eventfd_test.cpp b/tests/eventfd_test.cpp
index 68d9192..3c303c2 100644
--- a/tests/eventfd_test.cpp
+++ b/tests/eventfd_test.cpp
@@ -21,14 +21,16 @@
 
 #include <sys/eventfd.h>
 
+#include "utils.h"
+
 TEST(eventfd, smoke) {
-  unsigned int initial_value = 2;
-  int fd = eventfd(initial_value, O_NONBLOCK);
-  ASSERT_NE(fd, -1);
+  constexpr unsigned int kInitialValue = 2;
+  int fd = eventfd(kInitialValue, EFD_NONBLOCK);
+  ASSERT_NE(-1, fd);
 
   eventfd_t value = 123;
   ASSERT_EQ(0, eventfd_read(fd, &value));
-  ASSERT_EQ(initial_value, value);
+  ASSERT_EQ(kInitialValue, value);
 
   // Reading clears the counter.
   ASSERT_EQ(-1, eventfd_read(fd, &value));
@@ -44,3 +46,49 @@
 
   close(fd);
 }
+
+TEST(eventfd, cloexec) {
+  constexpr unsigned int kInitialValue = 2;
+  int fd = eventfd(kInitialValue, EFD_CLOEXEC);
+  ASSERT_NE(-1, fd);
+  AssertCloseOnExec(fd, true);
+
+  eventfd_t value = 123;
+  ASSERT_EQ(0, eventfd_read(fd, &value));
+  ASSERT_EQ(kInitialValue, value);
+
+  close(fd);
+
+  fd = eventfd(kInitialValue, EFD_NONBLOCK | EFD_CLOEXEC);
+  ASSERT_NE(-1, fd);
+  AssertCloseOnExec(fd, true);
+
+  value = 123;
+  ASSERT_EQ(0, eventfd_read(fd, &value));
+  ASSERT_EQ(kInitialValue, value);
+
+  close(fd);
+}
+
+TEST(eventfd, semaphore) {
+  int fd = eventfd(3, EFD_NONBLOCK | EFD_SEMAPHORE);
+  ASSERT_NE(-1, fd);
+
+  eventfd_t value = 123;
+  ASSERT_EQ(0, eventfd_read(fd, &value));
+  ASSERT_EQ(1U, value);
+
+  value = 123;
+  ASSERT_EQ(0, eventfd_read(fd, &value));
+  ASSERT_EQ(1U, value);
+
+  value = 123;
+  ASSERT_EQ(0, eventfd_read(fd, &value));
+  ASSERT_EQ(1U, value);
+
+  // The counter is cleared after the initial value decrements to 0.
+  ASSERT_EQ(-1, eventfd_read(fd, &value));
+  ASSERT_EQ(EAGAIN, errno);
+
+  close(fd);
+}