|
42 | 42 | //
|
43 | 43 | // unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help
|
44 | 44 | // you find this class if you're searching for one of those names.
|
45 |
| - |
46 |
| -#if defined(__BIONIC__) |
47 |
| -#include <android/fdsan.h> |
48 |
| -#endif |
49 |
| - |
50 | 45 | namespace android {
|
51 | 46 | namespace base {
|
52 | 47 |
|
53 | 48 | struct DefaultCloser {
|
54 |
| -#if defined(__BIONIC__) |
55 |
| - static void Tag(int fd, void* old_addr, void* new_addr) { |
56 |
| - uint64_t old_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD, |
57 |
| - reinterpret_cast<uint64_t>(old_addr)); |
58 |
| - uint64_t new_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD, |
59 |
| - reinterpret_cast<uint64_t>(new_addr)); |
60 |
| - android_fdsan_exchange_owner_tag(fd, old_tag, new_tag); |
61 |
| - } |
62 |
| - static void Close(int fd, void* addr) { |
63 |
| - uint64_t tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD, |
64 |
| - reinterpret_cast<uint64_t>(addr)); |
65 |
| - android_fdsan_close_with_tag(fd, tag); |
66 |
| - } |
67 |
| -#else |
68 | 49 | static void Close(int fd) {
|
69 | 50 | // Even if close(2) fails with EINTR, the fd will have been closed.
|
70 | 51 | // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone
|
71 | 52 | // else's fd.
|
72 | 53 | // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
|
73 | 54 | ::close(fd);
|
74 | 55 | }
|
75 |
| -#endif |
76 | 56 | };
|
77 | 57 |
|
78 | 58 | template <typename Closer>
|
79 | 59 | class unique_fd_impl final {
|
80 | 60 | public:
|
81 |
| - unique_fd_impl() {} |
| 61 | + unique_fd_impl() : value_(-1) {} |
82 | 62 |
|
83 |
| - explicit unique_fd_impl(int fd) { reset(fd); } |
| 63 | + explicit unique_fd_impl(int value) : value_(value) {} |
84 | 64 | ~unique_fd_impl() { reset(); }
|
85 | 65 |
|
86 |
| - unique_fd_impl(unique_fd_impl&& other) { reset(other.release()); } |
| 66 | + unique_fd_impl(unique_fd_impl&& other) : value_(other.release()) {} |
87 | 67 | unique_fd_impl& operator=(unique_fd_impl&& s) {
|
88 |
| - int fd = s.fd_; |
89 |
| - s.fd_ = -1; |
90 |
| - reset(fd, &s); |
| 68 | + reset(s.release()); |
91 | 69 | return *this;
|
92 | 70 | }
|
93 | 71 |
|
94 |
| - void reset(int new_value = -1) { reset(new_value, nullptr); } |
| 72 | + void reset(int new_value = -1) { |
| 73 | + if (value_ != -1) { |
| 74 | + Closer::Close(value_); |
| 75 | + } |
| 76 | + value_ = new_value; |
| 77 | + } |
95 | 78 |
|
96 |
| - int get() const { return fd_; } |
| 79 | + int get() const { return value_; } |
97 | 80 | operator int() const { return get(); }
|
98 | 81 |
|
99 | 82 | int release() __attribute__((warn_unused_result)) {
|
100 |
| - tag(fd_, this, nullptr); |
101 |
| - int ret = fd_; |
102 |
| - fd_ = -1; |
| 83 | + int ret = value_; |
| 84 | + value_ = -1; |
103 | 85 | return ret;
|
104 | 86 | }
|
105 | 87 |
|
106 | 88 | private:
|
107 |
| - void reset(int new_value, void* previous_tag) { |
108 |
| - if (fd_ != -1) { |
109 |
| - close(fd_, this); |
110 |
| - } |
111 |
| - |
112 |
| - fd_ = new_value; |
113 |
| - if (new_value != -1) { |
114 |
| - tag(new_value, previous_tag, this); |
115 |
| - } |
116 |
| - } |
117 |
| - |
118 |
| - int fd_ = -1; |
119 |
| - |
120 |
| - // Template magic to use Closer::Tag if available, and do nothing if not. |
121 |
| - // If Closer::Tag exists, this implementation is preferred, because int is a better match. |
122 |
| - // If not, this implementation is SFINAEd away, and the no-op below is the only one that exists. |
123 |
| - template <typename T = Closer> |
124 |
| - static auto tag(int fd, void* old_tag, void* new_tag) |
125 |
| - -> decltype(T::Tag(fd, old_tag, new_tag), void()) { |
126 |
| - T::Tag(fd, old_tag, new_tag); |
127 |
| - } |
128 |
| - |
129 |
| - template <typename T = Closer> |
130 |
| - static void tag(long, void*, void*) { |
131 |
| - // No-op. |
132 |
| - } |
133 |
| - |
134 |
| - // Same as above, to select between Closer::Close(int) and Closer::Close(int, void*). |
135 |
| - template <typename T = Closer> |
136 |
| - static auto close(int fd, void* tag_value) -> decltype(T::Close(fd, tag_value), void()) { |
137 |
| - T::Close(fd, tag_value); |
138 |
| - } |
139 |
| - |
140 |
| - template <typename T = Closer> |
141 |
| - static auto close(int fd, void*) -> decltype(T::Close(fd), void()) { |
142 |
| - T::Close(fd); |
143 |
| - } |
| 89 | + int value_; |
144 | 90 |
|
145 | 91 | unique_fd_impl(const unique_fd_impl&);
|
146 | 92 | void operator=(const unique_fd_impl&);
|
|
0 commit comments