Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13ea01db authored by Josh Gao's avatar Josh Gao
Browse files

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
parent faa14b94
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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() {
+2 −1
Original line number Diff line number Diff line
@@ -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>

/*
+22 −12
Original line number Diff line number Diff line
@@ -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