diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index abf481b3139c025c7057bbb27c259db14f2966b7..22eb4d2f051b7663f3d8e34469ef7a094dda3449 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 @@ bool forward_targets_are_valid(const std::string& source, const std::string& des
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 3586da8612d8aa06845af8b2aed77736afc729b2..639f8eb22e60a62fddc543717775d7aaba5991c8 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 ab41c55f079daa8d891fe019fac67f582ec3acbd..869e60f580e40a1b0564449629ebd9bf9377693a 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 @@ class unique_fd final {
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