Merge "adb/base: allow use of unique_fd inside adb."
am: 210fdc2742
* commit '210fdc2742d3cadaa2f8255ad22b4a2b7bdbf743':
adb/base: allow use of unique_fd inside adb.
Change-Id: Ic7d36d38343f46a541452ca6f6b622f3c5c74c26
This commit is contained in:
commit
881b440b7a
3 changed files with 33 additions and 13 deletions
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue