/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OHOS_FILEMGMT_FDSAN_H #define OHOS_FILEMGMT_FDSAN_H #include struct fdsan_fd { fdsan_fd() = default; explicit fdsan_fd(int fd) { reset(fd); } fdsan_fd(const fdsan_fd& copy) = delete; fdsan_fd(fdsan_fd&& move) { *this = std::move(move); } ~fdsan_fd() { reset(); } fdsan_fd& operator=(const fdsan_fd& copy) = delete; fdsan_fd& operator=(fdsan_fd&& move) { if (this == &move) { return *this; } reset(); if (move.fd_ != -1) { fd_ = move.fd_; move.fd_ = -1; // Acquire ownership from the moved-from object. exchange_tag(fd_, move.tag(), tag()); } return *this; } int get() { return fd_; } void reset(int new_fd = -1) { if (fd_ != -1) { close(fd_, tag()); fd_ = -1; } if (new_fd != -1) { fd_ = new_fd; // Acquire ownership of the presumably unowned fd. exchange_tag(fd_, 0, tag()); } } private: int fd_ = -1; // Use the address of object as the file tag uint64_t tag() { return reinterpret_cast(this); } static void exchange_tag(int fd, uint64_t old_tag, uint64_t new_tag) { if (&fdsan_exchange_owner_tag) { fdsan_exchange_owner_tag(fd, old_tag, new_tag); } } static int close(int fd, uint64_t tag) { if (&fdsan_close_with_tag) { return fdsan_close_with_tag(fd, tag); } } }; #endif // OHOS_FILEMGMT_FDSAN_H