From 13ea01db451b3993d175110a3336a58482be883d Mon Sep 17 00:00:00 2001 From: Josh Gao <jmgao@google.com> Date: Fri, 13 May 2016 14:52:06 -0700 Subject: [PATCH] adb/base: allow use of unique_fd inside adb. adb implements its own file descriptor emulation layer on Windows, which requires the use of adb_close instead of close throughout the codebase. Add a template argument to unique_fd that allows for this. Bug: http://b/28347842 Change-Id: I6397261f4973d49f2f8e04257bf67b348585bb63 --- adb/adb_utils.h | 9 +++++++ adb/sysdeps.h | 3 ++- base/include/android-base/unique_fd.h | 34 +++++++++++++++++---------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/adb/adb_utils.h b/adb/adb_utils.h index abf481b313..22eb4d2f05 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 3586da8612..639f8eb22e 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 ab41c55f07..869e60f580 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 -- GitLab