1 /** 2 * Copyright (c) 2021-2022 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 LIBPANDABASE_OS_UNIQUE_FD_H 17 #define LIBPANDABASE_OS_UNIQUE_FD_H 18 19 #ifdef PANDA_TARGET_UNIX 20 #include "platforms/unix/libpandabase/unique_fd.h" 21 #elif PANDA_TARGET_WINDOWS 22 #include "platforms/windows/libpandabase/unique_fd.h" 23 #else 24 #error "Unsupported platform" 25 #endif // PANDA_TARGET_UNIX 26 27 #include "os/failure_retry.h" 28 #include "utils/logger.h" 29 30 #include <unistd.h> 31 32 namespace panda::os::unique_fd { 33 34 class UniqueFd { 35 public: 36 explicit UniqueFd(int fd = -1) noexcept 37 { 38 Reset(fd); 39 } 40 41 UniqueFd(const UniqueFd &other_fd) = delete; 42 UniqueFd &operator=(const UniqueFd &other_fd) = delete; 43 UniqueFd(UniqueFd && other_fd)44 UniqueFd(UniqueFd &&other_fd) noexcept 45 { 46 Reset(other_fd.Release()); 47 } 48 49 UniqueFd &operator=(UniqueFd &&other_fd) noexcept 50 { 51 Reset(other_fd.Release()); 52 return *this; 53 } 54 ~UniqueFd()55 ~UniqueFd() 56 { 57 Reset(); 58 } 59 Release()60 int Release() noexcept 61 { 62 int fd = fd_; 63 fd_ = -1; 64 return fd; 65 } 66 67 void Reset(int new_fd = -1) 68 { 69 if (fd_ != -1) { 70 ASSERT(new_fd != fd_); 71 DefaultCloser(fd_); 72 } 73 fd_ = new_fd; 74 } 75 Get()76 int Get() const noexcept 77 { 78 return fd_; 79 } 80 IsValid()81 bool IsValid() const noexcept 82 { 83 return fd_ != -1; 84 } 85 86 private: DefaultCloser(int fd)87 static void DefaultCloser(int fd) 88 { 89 LOG_IF(PANDA_FAILURE_RETRY(::close(fd)) != 0, FATAL, COMMON) << "Incorrect fd: " << fd; 90 } 91 92 int fd_ = -1; 93 }; 94 95 } // namespace panda::os::unique_fd 96 97 #endif // LIBPANDABASE_OS_UNIQUE_FD_H 98