Introduce api to track fd ownership in libc.

Add two functions to allow objects that own a file descriptor to
enforce that only they can close their file descriptor.

Use them in FILE* and DIR*.

Bug: http://b/110100358
Test: bionic_unit_tests
Test: aosp/master boots without errors
Test: treehugger
Change-Id: Iecd6e8b26c62217271e0822dc3d2d7888b091a45
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 6282ec3..d499ddb 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -192,12 +192,6 @@
   errno = 0;
   ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1);
   ASSERT_EQ(EINVAL, errno);
-
-  // The underlying fd can't be closed.
-  ASSERT_EQ(0, close(fileno(fp)));
-  errno = 0;
-  ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1);
-  ASSERT_EQ(EBADF, errno);
   fclose(fp);
 }
 
@@ -268,12 +262,6 @@
   errno = 0;
   ASSERT_EQ(getline(&buffer, NULL, fp), -1);
   ASSERT_EQ(EINVAL, errno);
-
-  // The underlying fd can't be closed.
-  ASSERT_EQ(0, close(fileno(fp)));
-  errno = 0;
-  ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1);
-  ASSERT_EQ(EBADF, errno);
   fclose(fp);
 }
 
@@ -869,14 +857,16 @@
 TEST(STDIO_TEST, fprintf_failures_7229520) {
   // http://b/7229520
   FILE* fp;
+  int fd_rdonly = open("/dev/null", O_RDONLY);
+  ASSERT_NE(-1, fd_rdonly);
 
   // Unbuffered case where the fprintf(3) itself fails.
   ASSERT_NE(nullptr, fp = tmpfile());
   setbuf(fp, NULL);
   ASSERT_EQ(4, fprintf(fp, "epic"));
-  ASSERT_EQ(0, close(fileno(fp)));
+  ASSERT_NE(-1, dup2(fd_rdonly, fileno(fp)));
   ASSERT_EQ(-1, fprintf(fp, "fail"));
-  ASSERT_EQ(-1, fclose(fp));
+  ASSERT_EQ(0, fclose(fp));
 
   // Buffered case where we won't notice until the fclose(3).
   // It's likely this is what was actually seen in http://b/7229520,
@@ -884,7 +874,7 @@
   // disappointment. Remember to check fclose(3)'s return value, kids!
   ASSERT_NE(nullptr, fp = tmpfile());
   ASSERT_EQ(4, fprintf(fp, "epic"));
-  ASSERT_EQ(0, close(fileno(fp)));
+  ASSERT_NE(-1, dup2(fd_rdonly, fileno(fp)));
   ASSERT_EQ(4, fprintf(fp, "fail"));
   ASSERT_EQ(-1, fclose(fp));
 }
@@ -1916,7 +1906,6 @@
   AssertCloseOnExec(fileno(fp), true);
 
   fclose(fp);
-  close(fd);
 }
 
 TEST(STDIO_TEST, freopen_CLOEXEC) {