Adds quick_exit(3) and at_quick_exit(3) from freebsd

Change-Id: I4fe88abd8f7b8aa45e58aeb2529d59a8d555d338
diff --git a/tests/Android.mk b/tests/Android.mk
index 94474ff..fccf3f1 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -40,6 +40,9 @@
 
 test_cflags += -D__STDC_LIMIT_MACROS  # For glibc.
 
+test_cppflags = \
+    -std=gnu++11 \
+
 libBionicStandardTests_src_files := \
     buffer_tests.cpp \
     ctype_test.cpp \
@@ -91,6 +94,9 @@
 libBionicStandardTests_cflags := \
     $(test_cflags) \
 
+libBionicStandardTests_cppflags := \
+    $(test_cppflags) \
+
 libBionicStandardTests_ldlibs_host := \
     -lrt \
 
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index bb395f0..fc0f0e1 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -203,6 +203,52 @@
   ASSERT_DOUBLE_EQ(1.23, strtold("1.23", NULL));
 }
 
+TEST(stdlib, quick_exit) {
+  pid_t pid = fork();
+  ASSERT_NE(-1, pid) << strerror(errno);
+
+  if (pid == 0) {
+    quick_exit(99);
+  }
+
+  int status;
+  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(99, WEXITSTATUS(status));
+}
+
+static int quick_exit_status = 0;
+
+static void quick_exit_1(void) {
+  ASSERT_EQ(quick_exit_status, 0);
+  quick_exit_status = 1;
+}
+
+static void quick_exit_2(void) {
+  ASSERT_EQ(quick_exit_status, 1);
+}
+
+static void not_run(void) {
+  FAIL();
+}
+
+TEST(stdlib, at_quick_exit) {
+  pid_t pid = fork();
+  ASSERT_NE(-1, pid) << strerror(errno);
+
+  if (pid == 0) {
+    ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
+    ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
+    atexit(not_run);
+    quick_exit(99);
+  }
+
+  int status;
+  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(99, WEXITSTATUS(status));
+}
+
 TEST(unistd, _Exit) {
   int pid = fork();
   ASSERT_NE(-1, pid) << strerror(errno);