diff --git a/libc/bionic/scandir.cpp b/libc/bionic/scandir.cpp
new file mode 100644
index 0000000..dd22b22
--- /dev/null
+++ b/libc/bionic/scandir.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "private/ScopedReaddir.h"
+
+// A smart pointer to the scandir dirent**.
+class ScandirResult {
+ public:
+  ScandirResult() : names_(NULL), size_(0), capacity_(0) {
+  }
+
+  ~ScandirResult() {
+    while (size_ > 0) {
+      free(names_[--size_]);
+    }
+    free(names_);
+  }
+
+  size_t size() {
+    return size_;
+  }
+
+  dirent** release() {
+    dirent** result = names_;
+    names_ = NULL;
+    size_ = capacity_ = 0;
+    return result;
+  }
+
+  bool Add(dirent* entry) {
+    if (size_ >= capacity_) {
+      size_t new_capacity = capacity_ + 32;
+      dirent** new_names = (dirent**) realloc(names_, new_capacity * sizeof(dirent*));
+      if (new_names == NULL) {
+        return false;
+      }
+      names_ = new_names;
+      capacity_ = new_capacity;
+    }
+
+    dirent* copy = CopyDirent(entry);
+    if (copy == NULL) {
+      return false;
+    }
+    names_[size_++] = copy;
+    return true;
+  }
+
+  void Sort(int (*comparator)(const dirent**, const dirent**)) {
+    // If we have entries and a comparator, sort them.
+    if (size_ > 0 && comparator != NULL) {
+      qsort(names_, size_, sizeof(dirent*), (int (*)(const void*, const void*)) comparator);
+    }
+  }
+
+ private:
+  dirent** names_;
+  size_t size_;
+  size_t capacity_;
+
+  static dirent* CopyDirent(dirent* original) {
+    // Allocate the minimum number of bytes necessary, rounded up to a 4-byte boundary.
+    size_t size = ((original->d_reclen + 3) & ~3);
+    dirent* copy = (dirent*) malloc(size);
+    memcpy(copy, original, original->d_reclen);
+    return copy;
+  }
+
+  // Disallow copy and assignment.
+  ScandirResult(const ScandirResult&);
+  void operator=(const ScandirResult&);
+};
+
+int scandir(const char* dirname, dirent*** name_list,
+            int (*filter)(const dirent*),
+            int (*comparator)(const dirent**, const dirent**)) {
+  ScopedReaddir reader(dirname);
+  if (reader.IsBad()) {
+    return -1;
+  }
+
+  ScandirResult names;
+  dirent* entry;
+  while ((entry = reader.ReadEntry()) != NULL) {
+    // If we have a filter, skip names that don't match.
+    if (filter != NULL && !(*filter)(entry)) {
+      continue;
+    }
+    names.Add(entry);
+  }
+
+  names.Sort(comparator);
+
+  size_t size = names.size();
+  *name_list = names.release();
+  return size;
+}
