Merge "Separate properties by selabel"
diff --git a/libc/Android.mk b/libc/Android.mk
index 4182505..ba3e5aa 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -949,6 +949,7 @@
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
+$(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_openbsd_src_files))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES_EXCLUDE,libc_openbsd_src_files_exclude))
 include $(BUILD_STATIC_LIBRARY)
 
diff --git a/libc/private/ScopedPthreadMutexLocker.h b/libc/private/ScopedPthreadMutexLocker.h
index 43dbdc1..58462e3 100644
--- a/libc/private/ScopedPthreadMutexLocker.h
+++ b/libc/private/ScopedPthreadMutexLocker.h
@@ -34,7 +34,7 @@
  private:
   pthread_mutex_t* mu_;
 
-  DISALLOW_COPY_AND_ASSIGN(ScopedPthreadMutexLocker);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPthreadMutexLocker);
 };
 
 #endif // SCOPED_PTHREAD_MUTEX_LOCKER_H
diff --git a/tests/Android.mk b/tests/Android.mk
index 86c141a..7786a73 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -236,6 +236,8 @@
 
 libBionicGtestMain_cppflags := $(test_cppflags)
 
+libBionicGtestMain_static_libraries := libbase
+
 module := libBionicGtestMain
 module_tag := optional
 build_type := target
@@ -260,6 +262,8 @@
 
 libBionicCtsGtestMain_cppflags := $(test_cppflags) -DUSING_GTEST_OUTPUT_FORMAT \
 
+libBionicCtsGtestMain_static_libraries := libbase
+
 module := libBionicCtsGtestMain
 module_tag := optional
 build_type := target
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 3b9f6b9..b707a4a 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -34,6 +34,8 @@
 #include <utility>
 #include <vector>
 
+#include <base/stringprintf.h>
+
 #ifndef TEMP_FAILURE_RETRY
 
 /* Used to retry syscalls that can return EINTR. */
@@ -575,27 +577,15 @@
   exit(result);
 }
 
-#if defined(__APPLE__)
-
-static int pipe2(int pipefd[2], int flags) {
-  int ret = pipe(pipefd);
-  if (ret != -1) {
-    ret = fcntl(pipefd[0], F_SETFL, flags);
-  }
-  if (ret != -1) {
-    ret = fcntl(pipefd[1], F_SETFL, flags);
-  }
-  return ret;
-}
-
-#endif
-
 static ChildProcInfo RunChildProcess(const std::string& test_name, int testcase_id, int test_id,
                                      int argc, char** argv) {
   int pipefd[2];
-  int ret = pipe2(pipefd, O_NONBLOCK);
-  if (ret == -1) {
-    perror("pipe2 in RunTestInSeparateProc");
+  if (pipe(pipefd) == -1) {
+    perror("pipe in RunTestInSeparateProc");
+    exit(1);
+  }
+  if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) {
+    perror("fcntl in RunTestInSeparateProc");
     exit(1);
   }
   pid_t pid = fork();
@@ -685,6 +675,30 @@
   return timeout_child_count;
 }
 
+static void ReadChildProcOutput(std::vector<TestCase>& testcase_list,
+                                std::vector<ChildProcInfo>& child_proc_list) {
+  for (const auto& child_proc : child_proc_list) {
+    TestCase& testcase = testcase_list[child_proc.testcase_id];
+    int test_id = child_proc.test_id;
+    while (true) {
+      char buf[1024];
+      ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
+      if (bytes_read > 0) {
+        buf[bytes_read] = '\0';
+        testcase.GetTest(test_id).AppendTestOutput(buf);
+      } else if (bytes_read == 0) {
+        break; // Read end.
+      } else {
+        if (errno == EAGAIN) {
+          break;
+        }
+        perror("failed to read child_read_fd");
+        exit(1);
+      }
+    }
+  }
+}
+
 static void WaitChildProcs(std::vector<TestCase>& testcase_list,
                            std::vector<ChildProcInfo>& child_proc_list) {
   size_t finished_child_count = 0;
@@ -709,6 +723,7 @@
       finished_child_count += CheckChildProcTimeout(child_proc_list);
     }
 
+    ReadChildProcOutput(testcase_list, child_proc_list);
     if (finished_child_count > 0) {
       return;
     }
@@ -742,26 +757,6 @@
     kill(child_proc.pid, SIGKILL);
     WaitForOneChild(child_proc.pid);
   }
-
-  while (true) {
-    char buf[1024];
-    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(child_proc.child_read_fd, buf, sizeof(buf) - 1));
-    if (bytes_read > 0) {
-      buf[bytes_read] = '\0';
-      testcase.GetTest(test_id).AppendTestOutput(buf);
-    } else if (bytes_read == 0) {
-      break; // Read end.
-    } else {
-      if (errno == EAGAIN) {
-        // No data is available. This rarely happens, only when the child process created other
-        // processes which have not exited so far. But the child process has already exited or
-        // been killed, so the test has finished, and we shouldn't wait further.
-        break;
-      }
-      perror("read child_read_fd in RunTestInSeparateProc");
-      exit(1);
-    }
-  }
   close(child_proc.child_read_fd);
 
   if (child_proc.timed_out) {
@@ -780,8 +775,14 @@
     testcase.GetTest(test_id).AppendTestOutput(buf);
 
   } else {
-    testcase.SetTestResult(test_id, WEXITSTATUS(child_proc.exit_status) == 0 ?
-                           TEST_SUCCESS : TEST_FAILED);
+    int exitcode = WEXITSTATUS(child_proc.exit_status);
+    testcase.SetTestResult(test_id, exitcode == 0 ? TEST_SUCCESS : TEST_FAILED);
+    if (exitcode != 0) {
+      std::string s = android::base::StringPrintf("%s exited with exitcode %d.\n",
+                                                  testcase.GetTestName(test_id).c_str(),
+                                                  exitcode);
+      testcase.GetTest(test_id).AppendTestOutput(s);
+    }
   }
 }