Fix various ftw/nftw "shall fail"s from POSIX.

POSIX says ftw/nftw "shall fail" in various cases where BSD's fts_open
doesn't. Since our ftw/nftw are written in terms of fts_open, add a back
door so we can hint to ourselves when we should have the POSIX semantics.

Also pull several O_CLOEXEC and don't-null-check-before-free cleanups
from upstream, and add a couple of tests.

Bug: http://b/31152735
Test: ran bionic tests and LTP "nftw01" test
Change-Id: Ib05facacc1da4c8b2ab48e9ecce88f11a5406630
diff --git a/libc/bionic/ftw.cpp b/libc/bionic/ftw.cpp
index 2123619..71882b3 100644
--- a/libc/bionic/ftw.cpp
+++ b/libc/bionic/ftw.cpp
@@ -25,7 +25,9 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-static int do_nftw(const char *path,
+extern "C" FTS* __fts_open(char* const*, int, int (*)(const FTSENT**, const FTSENT**));
+
+static int do_nftw(const char* path,
                    int (*ftw_fn)(const char*, const struct stat*, int),
                    int (*nftw_fn)(const char*, const struct stat*, int, FTW*),
                    int nfds,
@@ -47,7 +49,7 @@
 
   // Call fts_open.
   char* const paths[2] = { const_cast<char*>(path), nullptr };
-  FTS* fts = fts_open(paths, fts_options, nullptr);
+  FTS* fts = __fts_open(paths, fts_options | FTS_FOR_FTW, nullptr);
   if (fts == nullptr) {
     return -1;
   }
@@ -64,6 +66,9 @@
         if (postorder || access(cur->fts_path, R_OK) == -1) continue;
         fn_flag = FTW_D;
         break;
+      case FTS_DC:
+        // POSIX says nftw "shall not report" directories causing loops (http://b/31152735).
+        continue;
       case FTS_DNR:
         fn_flag = FTW_DNR;
         break;
@@ -85,10 +90,6 @@
       case FTS_SLNONE:
         fn_flag = (nftw_fn != nullptr) ? FTW_SLN : FTW_NS;
         break;
-      case FTS_DC:
-        errno = ELOOP;
-        error = -1;
-        continue;
       default:
         error = -1;
         continue;