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 #ifndef _WIN32 19 #include <unistd.h> 20 #endif // !_WIN32 21 22 namespace OHOS { 23 class DefaultDeleter { 24 public: Close(int fd)25 static void Close(int fd) 26 { 27 if (fd >= 0) { 28 #ifdef _WIN32 29 Close(fd); 30 #else 31 close(fd); 32 #endif 33 } 34 } 35 }; 36 37 template<typename Deleter> 38 class UniqueFdAddDeletor; 39 template<typename Deleter> 40 bool operator==(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 41 template<typename Deleter> 42 bool operator!=(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 43 template<typename Deleter> 44 bool operator>=(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 45 template<typename Deleter> 46 bool operator>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 47 template<typename Deleter> 48 bool operator<=(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 49 template<typename Deleter> 50 bool operator<(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 51 52 template<typename Deleter = DefaultDeleter> 53 class UniqueFdAddDeletor final { 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 60 friend bool operator><Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 61 62 friend bool operator<=<Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 63 64 friend bool operator< <Deleter>(const int& lhs, const UniqueFdAddDeletor<Deleter>& rhs); 65 66 public: UniqueFdAddDeletor(const int & value)67 explicit UniqueFdAddDeletor(const int& value) 68 : fd_(value) 69 { 70 } UniqueFdAddDeletor()71 UniqueFdAddDeletor() 72 : fd_(-1) 73 { 74 } ~UniqueFdAddDeletor()75 ~UniqueFdAddDeletor() 76 { 77 Reset(-1); 78 } 79 80 // get fd out Release()81 int Release() 82 { 83 int tmp = fd_; 84 fd_ = -1; 85 return tmp; 86 } 87 88 // this is dangerous, when you use it , you should know it, donot operator on the ret 89 operator int() const 90 { 91 return Get(); 92 } // NOLINT 93 // this is dangerous, when you use it , you should know it, donot operator on the ret Get()94 int Get() const 95 { 96 return fd_; 97 } 98 99 // we need move fd from one to another UniqueFdAddDeletor(UniqueFdAddDeletor && rhs)100 UniqueFdAddDeletor(UniqueFdAddDeletor && rhs) 101 { 102 int rhsfd = rhs.Release(); 103 fd_ = rhsfd; 104 } 105 106 UniqueFdAddDeletor& operator=(UniqueFdAddDeletor && rhs) 107 { 108 int rhsfd = rhs.Release(); 109 Reset(rhsfd); 110 return *this; 111 } 112 113 bool operator==(const int& rhs) const 114 { 115 return fd_ == rhs; 116 } 117 118 bool operator!=(const int& rhs) const 119 { 120 return !(fd_ == rhs); 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 bool operator<=(const int& rhs) const 133 { 134 return fd_ <= rhs; 135 } 136 137 bool operator<(const int& rhs) const 138 { 139 return fd_ < rhs; 140 } 141 142 private: 143 int fd_ = -1; 144 Reset(int newValue)145 void Reset(int newValue) 146 { 147 if (fd_ >= 0) { 148 Deleter::Close(fd_); 149 } 150 fd_ = newValue; 151 } 152 153 // disallow copy ctor and copy assign 154 UniqueFdAddDeletor(const UniqueFdAddDeletor& rhs) = delete; 155 UniqueFdAddDeletor& operator=(const UniqueFdAddDeletor& rhs) = delete; 156 }; 157 158 template<typename Deleter = DefaultDeleter> 159 bool operator==(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 160 { 161 return lhs == uniqueFd.fd_; 162 } 163 164 template<typename Deleter = DefaultDeleter> 165 bool operator!=(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 166 { 167 return !(lhs == uniqueFd.fd_); 168 } 169 170 template<typename Deleter = DefaultDeleter> 171 bool operator>=(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 172 { 173 return lhs >= uniqueFd.fd_; 174 } 175 176 template<typename Deleter = DefaultDeleter> 177 bool operator>(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 178 { 179 return lhs > uniqueFd.fd_; 180 } 181 182 template<typename Deleter = DefaultDeleter> 183 bool operator<=(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 184 { 185 return lhs <= uniqueFd.fd_; 186 } 187 188 template<typename Deleter = DefaultDeleter> 189 bool operator<(const int& lhs, const UniqueFdAddDeletor<Deleter>& uniqueFd) 190 { 191 return lhs < uniqueFd.fd_; 192 } 193 194 using UniqueFd = UniqueFdAddDeletor<DefaultDeleter>; 195 } // namespace OHOS 196 #endif 197