Merge "adb/base: allow use of unique_fd inside adb." am: 210fdc2742
am: 881b440b7a

* commit '881b440b7a228e065d4b42ec71add07fbcb336c4':
  adb/base: allow use of unique_fd inside adb.

Change-Id: Ib1c437bcc6462235b8a753fb8cdedb9ff7261e9c
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index abf481b..22eb4d2 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -20,6 +20,7 @@
 #include <string>
 
 #include <android-base/macros.h>
+#include <android-base/unique_fd.h>
 
 void close_stdin();
 
@@ -51,6 +52,14 @@
                                std::string* error);
 
 // Helper to automatically close an FD when it goes out of scope.
+struct AdbCloser {
+    static void Close(int fd) {
+        adb_close(fd);
+    }
+};
+
+using unique_fd = android::base::unique_fd_impl<AdbCloser>;
+
 class ScopedFd {
   public:
     ScopedFd() {
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 3586da8..639f8eb 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -29,8 +29,9 @@
 #include <string>
 #include <vector>
 
-// Include this before open/unlink are defined as macros below.
+// Include this before open/close/unlink are defined as macros below.
 #include <android-base/errors.h>
+#include <android-base/unique_fd.h>
 #include <android-base/utf8.h>
 
 /*
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index ab41c55..869e60f 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -39,25 +39,33 @@
 namespace android {
 namespace base {
 
-class unique_fd final {
+struct DefaultCloser {
+  static void Close(int fd) {
+    // Even if close(2) fails with EINTR, the fd will have been closed.
+    // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone
+    // else's fd.
+    // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
+    ::close(fd);
+  }
+};
+
+template <typename Closer>
+class unique_fd_impl final {
  public:
-  unique_fd() : value_(-1) {}
+  unique_fd_impl() : value_(-1) {}
 
-  explicit unique_fd(int value) : value_(value) {}
-  ~unique_fd() { clear(); }
+  explicit unique_fd_impl(int value) : value_(value) {}
+  ~unique_fd_impl() { clear(); }
 
-  unique_fd(unique_fd&& other) : value_(other.release()) {}
-  unique_fd& operator=(unique_fd&& s) {
+  unique_fd_impl(unique_fd_impl&& other) : value_(other.release()) {}
+  unique_fd_impl& operator=(unique_fd_impl&& s) {
     reset(s.release());
     return *this;
   }
 
   void reset(int new_value) {
     if (value_ != -1) {
-      // Even if close(2) fails with EINTR, the fd will have been closed.
-      // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone else's fd.
-      // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
-      close(value_);
+      Closer::Close(value_);
     }
     value_ = new_value;
   }
@@ -78,10 +86,12 @@
  private:
   int value_;
 
-  unique_fd(const unique_fd&);
-  void operator=(const unique_fd&);
+  unique_fd_impl(const unique_fd_impl&);
+  void operator=(const unique_fd_impl&);
 };
 
+using unique_fd = unique_fd_impl<DefaultCloser>;
+
 }  // namespace base
 }  // namespace android