dumpstate: always include last ANR as a separate entry.

For consistency, as well as to make tooling easier.

Most of this change is an extended yak-shave to try and close DumpData
FDs in a consistent manner. Several layers of abstraction were assuming
that it was their job to close input FDs, leading to double closes in some
cases. These double closes are benign prior to this change to dump a
given DumpData twice, given that dumpstate is single threaded.

Bug: 68188758
Test: adb bugreport
Change-Id: I6302f4cb553139c0c26defb4859c4eca5b18ec93
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index c2c9071..6ff0dae 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -632,7 +632,7 @@
     struct dirent *d;
     char *newpath = NULL;
     const char *slash = "/";
-    int fd, retval = 0;
+    int retval = 0;
 
     if (!title.empty()) {
         printf("------ %s (%s) ------\n", title.c_str(), dir);
@@ -674,13 +674,13 @@
             }
             continue;
         }
-        fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
-        if (fd < 0) {
-            retval = fd;
+        android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
+        if (fd.get() < 0) {
+            retval = -1;
             printf("*** %s: %s\n", newpath, strerror(errno));
             continue;
         }
-        (*dump_from_fd)(NULL, newpath, fd);
+        (*dump_from_fd)(NULL, newpath, fd.get());
     }
     closedir(dirp);
     if (!title.empty()) {
@@ -699,11 +699,9 @@
     int flags = fcntl(fd, F_GETFL);
     if (flags == -1) {
         printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
-        close(fd);
         return -1;
     } else if (!(flags & O_NONBLOCK)) {
         printf("*** %s: fd must have O_NONBLOCK set.\n", path);
-        close(fd);
         return -1;
     }
     return DumpFileFromFdToFd(title, path, fd, STDOUT_FILENO, PropertiesHelper::IsDryRun());