1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef UNIQUE_FD_H 17 #define UNIQUE_FD_H 18 19 #include <unistd.h> 20 21 namespace OHOS { 22 class DefaultDeleter { 23 public: Close(int fd)24 static void Close(int fd) 25 { 26 if (fd >= 0) { 27 close(fd); 28 } 29 } 30 }; 31 32 template <typename Deleter> 33 class UniqueFdAddDeletor; 34 template <typename Deleter> 35 bool operator==(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 36 template <typename Deleter> 37 bool operator!=(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 38 template <typename Deleter> 39 bool operator>=(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 40 template <typename Deleter> 41 bool operator>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 42 template <typename Deleter> 43 bool operator<=(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 44 template <typename Deleter> 45 bool operator<(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 46 47 template <typename Deleter = DefaultDeleter> 48 class UniqueFdAddDeletor final { 49 50 friend bool operator==<Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 51 52 friend bool operator!=<Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 53 54 friend bool operator>=<Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 55 56 friend bool operator><Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 57 58 friend bool operator<=<Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 59 // clang-format off 60 friend bool operator< <Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 61 // clang-format on 62 public: UniqueFdAddDeletor(const int & value)63 explicit UniqueFdAddDeletor(const int& value) : fd_(value) {} UniqueFdAddDeletor()64 UniqueFdAddDeletor() : fd_(-1) {} ~UniqueFdAddDeletor()65 ~UniqueFdAddDeletor() 66 { 67 Reset(-1); 68 } 69 70 // get fd out Release()71 int Release() 72 { 73 int tmp = fd_; 74 fd_ = -1; 75 return tmp; 76 } 77 78 // this is dangerous, when you use it , you should know it, donot operator on the ret 79 operator int() const 80 { 81 return Get(); 82 } // NOLINT 83 // this is dangerous, when you use it , you should know it, donot operator on the ret Get()84 int Get() const 85 { 86 return fd_; 87 } 88 89 // we need move fd from one to another UniqueFdAddDeletor(UniqueFdAddDeletor && rhs)90 UniqueFdAddDeletor(UniqueFdAddDeletor&& rhs) 91 { 92 int rhsfd = rhs.Release(); 93 fd_ = rhsfd; 94 } 95 96 UniqueFdAddDeletor& operator=(UniqueFdAddDeletor&& rhs) 97 { 98 int rhsfd = rhs.Release(); 99 Reset(rhsfd); 100 return *this; 101 } 102 103 bool operator==(const int& rhs) const 104 { 105 return fd_ == rhs; 106 } 107 108 bool operator!=(const int& rhs) const 109 { 110 return !(fd_ == rhs); 111 } 112 bool operator>=(const int& rhs) const 113 { 114 return fd_ >= rhs; 115 } 116 117 bool operator>(const int& rhs) const 118 { 119 return fd_ > rhs; 120 } 121 122 bool operator<=(const int& rhs) const 123 { 124 return fd_ <= rhs; 125 } 126 127 bool operator<(const int& rhs) const 128 { 129 return fd_ < rhs; 130 } 131 132 private: 133 int fd_ = -1; 134 Reset(int newValue)135 void Reset(int newValue) 136 { 137 if (fd_ >= 0) { 138 Deleter::Close(fd_); 139 } 140 fd_ = newValue; 141 } 142 143 // disallow copy ctor and copy assign 144 UniqueFdAddDeletor(const UniqueFdAddDeletor& rhs) = delete; 145 UniqueFdAddDeletor& operator=(const UniqueFdAddDeletor& rhs) = delete; 146 }; 147 148 template <typename Deleter = DefaultDeleter> 149 bool operator==(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 150 { 151 return lhs == uniqueFd.fd_; 152 } 153 154 template <typename Deleter = DefaultDeleter> 155 bool operator!=(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 156 { 157 return !(lhs == uniqueFd.fd_); 158 } 159 160 template <typename Deleter = DefaultDeleter> 161 bool operator>=(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 162 { 163 return lhs >= uniqueFd.fd_; 164 } 165 166 template <typename Deleter = DefaultDeleter> 167 bool operator>(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 168 { 169 return lhs > uniqueFd.fd_; 170 } 171 172 template <typename Deleter = DefaultDeleter> 173 bool operator<=(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 174 { 175 return lhs <= uniqueFd.fd_; 176 } 177 178 template <typename Deleter = DefaultDeleter> 179 bool operator<(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 180 { 181 return lhs < uniqueFd.fd_; 182 } 183 184 using UniqueFd = UniqueFdAddDeletor<DefaultDeleter>; 185 } // namespace OHOS 186 #endif 187