Add POSIX qsort_r().

POSIX added this to issue 8, based on https://www.austingroupbugs.net/view.php?id=900.

This is an incompatibility with iOS, which is one reason why I hadn't
added this previously, but FreeBSD (upstream for both Android and iOS in
this case) already moved off their different qsort_r(), so it's possible
Apple will, and in the meantime, at least I now have the defense of
"POSIX says...".

Change-Id: Iab048a3a931010c3276a88d25eb56b38d4d608b1
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index f5e57a5..3216066 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -431,6 +431,31 @@
   ASSERT_STREQ("charlie", entries[2].name);
 }
 
+TEST(stdlib, qsort_r) {
+  struct s {
+    char name[16];
+    static int comparator(const void* lhs, const void* rhs, void* context) {
+      int* count_p = reinterpret_cast<int*>(context);
+      *count_p += 1;
+      return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
+    }
+  };
+  s entries[3];
+  strcpy(entries[0].name, "charlie");
+  strcpy(entries[1].name, "bravo");
+  strcpy(entries[2].name, "alpha");
+
+  int count;
+  void* context = &count;
+
+  count = 0;
+  qsort_r(entries, 3, sizeof(s), s::comparator, context);
+  ASSERT_STREQ("alpha", entries[0].name);
+  ASSERT_STREQ("bravo", entries[1].name);
+  ASSERT_STREQ("charlie", entries[2].name);
+  ASSERT_EQ(count, 3);
+}
+
 static void* TestBug57421_child(void* arg) {
   pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
   pthread_join(main_thread, nullptr);